Search code examples
rerror-handlingtry-catcherror-suppressionfitdistrplus

Suppress error message when using fitdist() from the fitdistrplus package


I am using certain functions from the fitdistrplus package as a part of a package I am creating.

I am attempting to prevent any error messages from displaying in the console when the functions are run and instead want to record the error messages in an error log that I am creating.

In most cases, using tryCatch() has allowed me to achieve this.

But specifically for the fitdist() function, I cannot suppress the error message being printed in the console even though the message is being written to the error log (meaning the tryCatch() expression is functioning).

I have replicated my issue in the code below.

library(fitdistrplus)

file.create("error_log.txt")

func_desc<-function(x){
  tryCatch({
    descdist(data = x)
  },error = function(e){
    write(x = paste(Sys.time(),"Error in func_desc :",e$message,sep = " "),file = "error_log.txt",append = T,sep = "\n")
  })
}

func_fit<-function(x,dist){
  tryCatch({
    fitdist(data = x,distr = dist)
  },error = function(e){
    write(x = paste(Sys.time(),"Error in func_fit :",e$message,sep = " "),file = "error_log.txt",append = T,sep = "\n")
  })
}

# Creating a vector of repeated values which will result in an error
test<-rep(x = 1,times = 10)

func_desc(x = test)
# Results in an error and the message is written to the error log and not printed in the console

func_fit(x = test,dist = "beta")
# Results in an error and the message is both written to the error log and printed in the console

I want to suppress this error message being printed by func_fit().

I have already tried the following alternatives:

  1. try() with silent = TRUE. The error message still gets printed.
  2. conditionMessage() gives the same result.
  3. withCallingHandlers() has been suggested in some posts and threads but I am unsure of how to implement it correctly.
  4. Using invisible() with the functions still prints the error.

Solution

  • This comes about because fitdist (or actually, mledist which is called by fitdist) is already doing some error catching. The original error is in optim and has been caught, and then mledist prints to the console the error message. So what you're seeing isn't really an error or even a warning, it's a print statement with the content of a caught error message.

    The bit of mledist that does this is:

        if (inherits(opttryerror, "try-error")) {
            warnings("The function optim encountered an error and stopped.")
            if (getOption("show.error.messages")) 
                print(attr(opttryerror, "condition"))
            return(list(estimate = rep(NA, length(vstart)), convergence = 100, 
                loglik = NA, hessian = NA, optim.function = opt.fun, 
                fix.arg = fix.arg, optim.method = meth, fix.arg.fun = fix.arg.fun, 
                counts = c(NA, NA)))
        }
    

    This isn't really good practice, precisely because it causes the problem you now have; it stops other people handling errors systematically.

    As you can see from that code, you could switch this off by setting the show.error.messages option to FALSE:

    options(show.error.messages = FALSE)
    

    but you want to be careful about that as you won't see any error messages for the rest of the R session. You definitely don't want to do it to someone else's session.

    Another alternative is to use sink("extra-error-messages.txt") to send all the printing to the console somewhere (maybe even to your error_log.txt but I'm not sure if that would cause problems with multiple things writing to it).