---
title: "Error Handling"
output:
  html_document:
    toc: false
vignette: >
  %\VignetteIndexEntry{Error Handling}
  %\VignetteEngine{knitr::rmarkdown}
  %\VignetteEncoding{UTF-8}
---

In any large scale experiment many things can and will go wrong.
The cluster might have an outage, jobs may run into resource limits or crash, subtle bugs in your code could be triggered or any other error condition might arise.
In these situations it is important to quickly determine what went wrong and to recompute only the minimal number of required jobs.

Therefore, before you submit anything you should use [`testJob()`](https://mllg.github.io/batchtools/reference/testJob) to catch errors that are easy to spot because they are raised in many or all jobs.
If `external` is set, this function runs the job without side effects in an independent R process on your local machine via `Rscript` similar as on the slave, redirects the output of the process to your R console, loads the job result and returns it.
If you do not set `external`, the job is executed is in the currently running R session, with the drawback that you might be unable to catch missing variable declarations or missing package dependencies.

By way of illustration here is a small example.
First, we create a temporary registry.
```{r, message = FALSE}
library(batchtools)
reg = makeRegistry(file.dir = NA, seed = 1)
```
```{r,include=FALSE}
if (dir.exists("/tmp"))
  reg$work.dir = "/tmp"
```
Ten jobs are created, two of them will throw an exception.
```{r}
flakeyFunction <- function(value) {
  if (value %in% c(2, 9)) stop("Ooops.")
  value^2
}
batchMap(flakeyFunction, 1:10)
```

Now that the jobs are defined, we can test jobs independently:
```{r}
testJob(id = 1)
```
In this case, testing the job with ID = 1 provides the appropriate result but testing the job with ID = 2 leads to an error:
```{r}
as.character(try(testJob(id = 2)))
```
When you have already submitted the jobs and suspect that something is going wrong, the first thing to do is to run [`getStatus()`](https://mllg.github.io/batchtools/reference/getStatus) to display a summary of the current state of the system.
```{r}
submitJobs()
waitForJobs()
getStatus()
```
The status message shows that two of the jobs could not be executed successfully.
To get the IDs of all jobs that failed due to an error we can use [`findErrors()`](https://mllg.github.io/batchtools/reference/findJobs) and to retrieve the actual error message, we can use [`getErrorMessages()`](https://mllg.github.io/batchtools/reference/getErrorMessages).
```{r}
findErrors()
getErrorMessages()
```
If we want to peek into the R log file of a job to see more context for the error we can use [`showLog()`](https://mllg.github.io/batchtools/reference/showLog) which opens a pager or use [`getLog()`](https://mllg.github.io/batchtools/reference/showLog) to get the log as character vector:
```{r}
writeLines(getLog(id = 9))
```

You can also grep for error or warning messages:
```{r}
ids = grepLogs(pattern = "ooops", ignore.case = TRUE)
print(ids)
```
