[tryExcept] New try Function

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

[tryExcept] New try Function

Ernest Benedito
Hi everyone,

When dealing with errors, sometimes I want to run a bunch of code when an error occurs.
For now I usually use a structure such as:

res <- tryCatch(expr, error = function(cond) cond) # or try(expr)

if (inherits(res, “error”)) # or inherits(res, “try-error”)
  # a bunch of code

I though it would be useful to have a function that does this naturally, so I came up with the attached function.

I would be glad to hear your insights and if you think it would make sense to add this function to R.

Best regards,
Ernest
______________________________________________
[hidden email] mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel
Reply | Threaded
Open this post in threaded view
|

Re: [tryExcept] New try Function

Emil
Hi Ernest,

To start: I don't see an attachment, I think they're not (always) allowed on this mailing-list. If you want to send something, text is your safest bet.
But regarding the issue of tryCatch: I think you're not fully using what it already can do. In almost all circumstances I've encountered the following works fine:
res <- tryCatch(expr, error = function(cond) {
  # a bunch of code
  # Some value to be stored in res
})
The only difference is that now "#abunchofcode" is run from inside a function, which means you're working in a different environment, and if you want to assign values to other variables you need to use <<- or assign.
For a modified function, I think it would be nice if there's a way to supply an expression instead of a function, so that evaluation (and assignment!) takes place in the same environment as the main code in the tryCatch (in expr). Is that what you made?
And with the current tryCatch, you could use something like this:
res <- tryCatch(expr, error=function(e) evalq({
  # a bunch of code
  # Some value for res
}, envir=parent.frame(4))) # The 4 is because some internal functions are involved, parent.frame(4) is the same environment as used by expr

Although this is cumbersome, and it gets even more cumbersome if you want to access the error-object in #abunchofcode, or use #abunchofcode to return to a higher level, so I get it you're looking for a more elegant solution.

Best regards,
Emil Bode
 
On 23/11/2018, 08:49, "R-devel on behalf of Ernest Benedito" <[hidden email] on behalf of [hidden email]> wrote:

    Hi everyone,
   
    When dealing with errors, sometimes I want to run a bunch of code when an error occurs.
    For now I usually use a structure such as:
   
    res <- tryCatch(expr, error = function(cond) cond) # or try(expr)
   
    if (inherits(res, “error”)) # or inherits(res, “try-error”)
      # a bunch of code
   
    I though it would be useful to have a function that does this naturally, so I came up with the attached function.
   
    I would be glad to hear your insights and if you think it would make sense to add this function to R.
   
    Best regards,
    Ernest
    ______________________________________________
    [hidden email] mailing list
    https://stat.ethz.ch/mailman/listinfo/r-devel
   

______________________________________________
[hidden email] mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel
Reply | Threaded
Open this post in threaded view
|

Re: [tryExcept] New try Function

Ernest Benedito
Hi Emil,

First, thanks for the response. As you mentioned, a lot of times tryCatch
does the work, as you can return a value. However, sometimes it is useful
to assign several variables when an error occurs. You could do it with <<-,
but I prefer to reduce it's usage unless completely necessary.

I guess that the attachment was missed in the moderation. Here it is the
function:

tryExcept <- function (expr,
                       except = {})
{
  doTryExcept <- function(expr, parentenv) {
    .Internal(.addCondHands("error", list(NULL), parentenv,
                            environment(), FALSE))
    expr
  }
  parentenv <- parent.frame()
  doTryExcept(return(expr), parentenv)
  invisible(except)
}

As you can see, the tryExcept function uses a simplified version of the
tryCatch architecture, but it allows you to pass by a second expression
that is evaluated in case an error occurs during the evaluation of the
first expression. It could even work as an infix operator:

`%except%` <- tryExcept

# dummy example
{foo <- "foo"} %except% {foo <- "foo bar"}
print(foo) # "foo"

{ foo <- "foo"
  stop()
} %except% {
  foo <- "foo bar"
}
print(foo) # "foo bar"

It's main downside is that you are not able to handle the error occured,
although there is the possibility to add a 'silent' parameter such as in
'try' in order to print the error if desired. All in all, this would be a
function for simple error handling, but I think it would be practical, and
you can always move to tryCatch if you need a more complex error handling.

I will be looking forward to hearing your insights.

Best,
Ernest Benedito

Missatge de Emil Bode <[hidden email]> del dia dv., 23 de nov. 2018
a les 13:17:

> Hi Ernest,
>
> To start: I don't see an attachment, I think they're not (always) allowed
> on this mailing-list. If you want to send something, text is your safest
> bet.
> But regarding the issue of tryCatch: I think you're not fully using what
> it already can do. In almost all circumstances I've encountered the
> following works fine:
> res <- tryCatch(expr, error = function(cond) {
>   # a bunch of code
>   # Some value to be stored in res
> })
> The only difference is that now "#abunchofcode" is run from inside a
> function, which means you're working in a different environment, and if you
> want to assign values to other variables you need to use <<- or assign.
> For a modified function, I think it would be nice if there's a way to
> supply an expression instead of a function, so that evaluation (and
> assignment!) takes place in the same environment as the main code in the
> tryCatch (in expr). Is that what you made?
> And with the current tryCatch, you could use something like this:
> res <- tryCatch(expr, error=function(e) evalq({
>   # a bunch of code
>   # Some value for res
> }, envir=parent.frame(4))) # The 4 is because some internal functions are
> involved, parent.frame(4) is the same environment as used by expr
>
> Although this is cumbersome, and it gets even more cumbersome if you want
> to access the error-object in #abunchofcode, or use #abunchofcode to return
> to a higher level, so I get it you're looking for a more elegant solution.
>
> Best regards,
> Emil Bode
>
> On 23/11/2018, 08:49, "R-devel on behalf of Ernest Benedito" <
> [hidden email] on behalf of [hidden email]> wrote:
>
>     Hi everyone,
>
>     When dealing with errors, sometimes I want to run a bunch of code when
> an error occurs.
>     For now I usually use a structure such as:
>
>     res <- tryCatch(expr, error = function(cond) cond) # or try(expr)
>
>     if (inherits(res, “error”)) # or inherits(res, “try-error”)
>       # a bunch of code
>
>     I though it would be useful to have a function that does this
> naturally, so I came up with the attached function.
>
>     I would be glad to hear your insights and if you think it would make
> sense to add this function to R.
>
>     Best regards,
>     Ernest
>     ______________________________________________
>     [hidden email] mailing list
>     https://stat.ethz.ch/mailman/listinfo/r-devel
>
>

        [[alternative HTML version deleted]]

______________________________________________
[hidden email] mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel
Reply | Threaded
Open this post in threaded view
|

Re: [tryExcept] New try Function

Andrew Redd
I have two related packages that are already submitted to CRAN but are
awaiting approval.  They are part of the R Documentation Task Force efforts
to improve documentation.  The exact function you are referring to I have
called `catch_condition()` and included it in my `testextra` package.  You
might also want to check out the `pkgcond` package which facilitates
creating informative conditions (errors, warnings, and messages).  These
conditions are automatically classed to tell you where the error is coming
from, the package and function, including class for reference methods.

https://github.com/RDocTaskForce/testextra
https://github.com/RDocTaskForce/pkgcond

On Fri, Nov 23, 2018 at 7:48 AM Ernest Benedito <[hidden email]>
wrote:

> Hi Emil,
>
> First, thanks for the response. As you mentioned, a lot of times tryCatch
> does the work, as you can return a value. However, sometimes it is useful
> to assign several variables when an error occurs. You could do it with <<-,
> but I prefer to reduce it's usage unless completely necessary.
>
> I guess that the attachment was missed in the moderation. Here it is the
> function:
>
> tryExcept <- function (expr,
>                        except = {})
> {
>   doTryExcept <- function(expr, parentenv) {
>     .Internal(.addCondHands("error", list(NULL), parentenv,
>                             environment(), FALSE))
>     expr
>   }
>   parentenv <- parent.frame()
>   doTryExcept(return(expr), parentenv)
>   invisible(except)
> }
>
> As you can see, the tryExcept function uses a simplified version of the
> tryCatch architecture, but it allows you to pass by a second expression
> that is evaluated in case an error occurs during the evaluation of the
> first expression. It could even work as an infix operator:
>
> `%except%` <- tryExcept
>
> # dummy example
> {foo <- "foo"} %except% {foo <- "foo bar"}
> print(foo) # "foo"
>
> { foo <- "foo"
>   stop()
> } %except% {
>   foo <- "foo bar"
> }
> print(foo) # "foo bar"
>
> It's main downside is that you are not able to handle the error occured,
> although there is the possibility to add a 'silent' parameter such as in
> 'try' in order to print the error if desired. All in all, this would be a
> function for simple error handling, but I think it would be practical, and
> you can always move to tryCatch if you need a more complex error handling.
>
> I will be looking forward to hearing your insights.
>
> Best,
> Ernest Benedito
>
> Missatge de Emil Bode <[hidden email]> del dia dv., 23 de nov.
> 2018
> a les 13:17:
>
> > Hi Ernest,
> >
> > To start: I don't see an attachment, I think they're not (always) allowed
> > on this mailing-list. If you want to send something, text is your safest
> > bet.
> > But regarding the issue of tryCatch: I think you're not fully using what
> > it already can do. In almost all circumstances I've encountered the
> > following works fine:
> > res <- tryCatch(expr, error = function(cond) {
> >   # a bunch of code
> >   # Some value to be stored in res
> > })
> > The only difference is that now "#abunchofcode" is run from inside a
> > function, which means you're working in a different environment, and if
> you
> > want to assign values to other variables you need to use <<- or assign.
> > For a modified function, I think it would be nice if there's a way to
> > supply an expression instead of a function, so that evaluation (and
> > assignment!) takes place in the same environment as the main code in the
> > tryCatch (in expr). Is that what you made?
> > And with the current tryCatch, you could use something like this:
> > res <- tryCatch(expr, error=function(e) evalq({
> >   # a bunch of code
> >   # Some value for res
> > }, envir=parent.frame(4))) # The 4 is because some internal functions are
> > involved, parent.frame(4) is the same environment as used by expr
> >
> > Although this is cumbersome, and it gets even more cumbersome if you want
> > to access the error-object in #abunchofcode, or use #abunchofcode to
> return
> > to a higher level, so I get it you're looking for a more elegant
> solution.
> >
> > Best regards,
> > Emil Bode
> >
> > On 23/11/2018, 08:49, "R-devel on behalf of Ernest Benedito" <
> > [hidden email] on behalf of [hidden email]> wrote:
> >
> >     Hi everyone,
> >
> >     When dealing with errors, sometimes I want to run a bunch of code
> when
> > an error occurs.
> >     For now I usually use a structure such as:
> >
> >     res <- tryCatch(expr, error = function(cond) cond) # or try(expr)
> >
> >     if (inherits(res, “error”)) # or inherits(res, “try-error”)
> >       # a bunch of code
> >
> >     I though it would be useful to have a function that does this
> > naturally, so I came up with the attached function.
> >
> >     I would be glad to hear your insights and if you think it would make
> > sense to add this function to R.
> >
> >     Best regards,
> >     Ernest
> >     ______________________________________________
> >     [hidden email] mailing list
> >     https://stat.ethz.ch/mailman/listinfo/r-devel
> >
> >
>
>         [[alternative HTML version deleted]]
>
> ______________________________________________
> [hidden email] mailing list
> https://stat.ethz.ch/mailman/listinfo/r-devel
>

        [[alternative HTML version deleted]]

______________________________________________
[hidden email] mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel