Search code examples
remailsendmailr

Sending Email from R - when Scheduled script Fails in Windows


I Have a Rscript file (Main_Script.R) which runs as a sheduled job in windows Task Scheduler every 30 Mins.Inside the Main_Script.R - i have around 13 scripts that runs every 30 mins.

I wanted to send Email from R - whenever an iteration is failed or haulted. I am using sendMailR package - and i have seen an post in SO how to send email with attachment from R in windows - on how to send emqil from R Windows.

But i am not sure about - how to send an email automatically with the error message - when the scheduled task iteration is failed or haulted.

My Main_Script.R - has source of all 13 codes.

source(paste(rootAddress,"Scripts/Part1.R",sep =''))
source(paste(rootAddress,"Scripts/Part2.R",sep =''))
:
:
:
:
source(paste(rootAddress,"Scripts/Part13.R",sep =''))

My Sheduled task looks like below with log file

"D:\xxx\R-3.0.2\bin\x64\Rscript.exe" "D:\xx\Batch_Processing\Batch_Processing_Run\Scripts\Main_Test.R" >> "D:\XXX\Batch_Processing\Batch_Processing_Run\error.txt" 2>&1

Update:

When the script encounters error - it should trigger email - with the erorr meassge and the script name or number -to denote which of the 13 scripts failed and send to a mail ID.


Solution

  • Here's a solution that wraps your script of sources:

    tryCatch({
    source("fail1.R")
    source("fail2.R")
    source("fail3.R")
    },
             error=function(e){cat("send email with error ",e$message,"\n")})
    

    My scripts are:

    if(x==1){stop("Fail One!")}
    

    and similar. Hence:

    > x=22
    > source("doall.R")
    > x=2
    > source("doall.R")
    send email with error  Fail Two! 
    

    So replace my cat with your email sending and job done. The error is passed as an argument to the handler so you can get the message from it.

    Here's how to do it with 13 scripts numbered as your example and identify which one went wrong:

    for(i in 1:13){
     try( {
          source(paste(rootAddress,"Scripts/Part",i,".R",sep =''))
          },
          error = function(e){mailMe(i, e$message)}
        )
    }
    

    Now you just need to write the mailMe function, which gets the number of the script and the error message. It might be something like this:

    mailMe = function(i, message){
      subject=paste("Error in script ",i)
      body = paste("Error was ",message," in script ",i)
      someSendmailRfunction(to="[email protected]", subject=subject,body=body, etc=etc)
    }
    

    Note you can test the mailMe function separately until it works.