3

I'm trying to close my logger instance in a finally block, as follows:

logger <- file("all.Rout", open="wt")           
sink(logger, type="message")                                 

tryCatch({
    warning('test')
    message("A")
    log('a')
    message("B")
}, error = function(e) {
}, finally = {
    sink(type="message")
    close(logger)
})

However, only message("A") is saved to log and nothing else is. If I do the follow, the problem is fixed:

logger <- file("all.Rout", open="wt")           
sink(logger, type="message")                                 

tryCatch({
    warning('test')
    message("A")
    log('a')
    message("B")
}, error = function(e) {
}, finally = {
})

sink(type="message")
close(logger)

However, I really need the closing to be in the finally block so that I can view the logs if an error was thrown.

How do I fix this?

user2763361
  • 3,789
  • 11
  • 45
  • 81

1 Answers1

3

The problem is that the default setting is not to print warnings as they happen. They are accumulated and then printed when convenient. So R doesn't think the finally block is a convenient time to print those warnings because you aren't ineractive at that point and might not see them. One work-around is to change the setting to report every warning as it happens rather than waiting till the current call is done. you can do that with this

logger <- file("log.txt", open="wt")           
sink(logger, type="message")                                 

tryCatch({
    ow<-options(warn=1)
    warning('test')
    message("A")
    log('a')
    message("B")
}, 
error = function(e) {
}, finally = {
    options(ow)
    sink(type="message")
    close(logger)
})

Here we change the options() at the beginning of the try block and then reset them in the finally.

The contents of the log file are then

Warning in doTryCatch(return(expr), name, parentenv, handler) : test
A

You'll notice in the other method the messages are reversed even though the warning come first. Again, R was just waiting till the end of the current call to return the warnings messages to you and that was after the tryCatch() finished running.

MrFlick
  • 195,160
  • 17
  • 277
  • 295
  • An alternative is to overwrite the option warning.expression ala: https://stackoverflow.com/questions/19433848/handling-errors-before-warnings-in-trycatch/19446931#19446931 – Hansi Aug 15 '14 at 13:27