[R-pkg-devel] best way the handle errors conditionally

Brian G. Peterson brian at braverock.com
Mon Mar 6 13:58:44 CET 2017


On Mon, 2017-03-06 at 11:17 +0100, Thierry Onkelinx wrote:
> I'd like your advice on handling errors conditionally within a
> function. Imagine a function that does several database operations.
> The user has the option to run them inside a transaction. So the code
> has somewhere near the top:
> 
> if (transaction) {
>     DBI::dbBegin(conn)
> }
> 
> At the end of the function there is a command which commits the
> transaction.
> 
> if (transaction) {
>     DBI::dbCommit(conn)
> }
> 
> If something goes wrong, one reverses the database operations by
> issuing the DBI::dbRollback(conn) command. The first option for
> issuing that is to use tryCatch(). The drawback is that the set of
> command can be a few hundred lines, which harms readability when
> wrapping them into a tryCatch().
> 
>  tryCatch(
>    {potentially long set of commands},
>     error = function(e){
>       if (transaction) {
>         dbRollback(conn)
>       }
>       stop(e)
>     }
> )
> 
> Another options I've found is to set options(error = function(){}) I
> assume that this has a permanent effect on the current R session? So
> I should reset that as a part of the error handling?
> 
> What would be recommended: tryCatch() or options(error = ...)? Or are
> there more / better solutions?

Specifically to DBI and SQL transaction support, you should consider
using dbWithTransaction(), which is designed to do exactly what you're
asking for here, with dbBegin, dbCommit, and dbRollback.

For tryCatch in this mode, which doesn't seem to be the best pattern,
I'd probably suggest wrapping complicated series of commands in
functions, and calling those within one or more tryCatch constructs. 
You would probably want to break it up so that you could call
dbRollback earlier than the very end of a long sequence of commands.

Regards,

Brian



More information about the R-package-devel mailing list