ropensci / drake

An R-focused pipeline toolkit for reproducibility and high-performance computing
https://docs.ropensci.org/drake
GNU General Public License v3.0
1.34k stars 128 forks source link

Uninformative error thrown by r_make when plan is not assigned/named "plan" #1334

Closed robitalec closed 3 years ago

robitalec commented 3 years ago

Prework

Description

Found an uninformative error thrown by drake if the plan in plan.R is not assigned to a variable named "plan" or assigned altogether. This happened by accident just copying over a plan to a new project, and it took me a moment to figure out what was going on. The same error is thrown if you assign the plan to a variable but not named "plan".

Reproducible example

_drake.R

source("scripts/plan.R")

drake_config(plan)

scripts/plan.R

# Load drake
library(drake)

drake_plan(
  printed = print('test')
)
drake::r_make()
Error in if (nrow(plan) < 1L) { : argument is of length zero
Error: callr subprocess failed: argument is of length zero
Type .Last.error.trace to see where the error occured
.Last.error.trace
 Stack trace:

 Process 99907:
 1. (function (r_args = list())  ...
 2. drake:::r_make(r_args = r_args)
 3. drake:::r_drake(source, drake::make_impl, list(), r_fn, r_args)
 4. base:::do.call(r_fn, r_args)
 5. (function (func, args = list(), libpath = .libPaths(), repos = default_repos(),  ...
 6. callr:::get_result(output = out, options)
 7. throw(newerr, parent = remerr[[2]])

 x callr subprocess failed: argument is of length zero 

 Process 100517:
 19. (function (source, d_fn, d_args)  ...
 20. base:::source(source)
 21. base:::withVisible(eval(ei, envir))
 22. base:::eval(ei, envir)
 23. base:::eval(ei, envir)
 24. drake:::drake_config(plan)
 25. drake:::sanitize_plan(plan, envir = envir)
 26. base:::.handleSimpleError(function (e)  ...
 27. h(simpleError(msg, call))

 x argument is of length zero 
wlandau commented 3 years ago

The issue is that plan() is a deprecated function in drake and you have not assigned your own object to the symbol plan. It will work if plan.R looks like this:

library(drake)
plan <- drake_plan( # Assign the plan to a variable.
  printed = print('test')
)
wlandau commented 3 years ago

The plan need not be called plan.

# plan.R
library(drake)
your_plan <- drake_plan( # Assign the plan to a variable.
  printed = print('test')
)

# _drake.R
source("plan.R")
drake_config(your_plan)
wlandau commented 3 years ago

Just improved the error message in the dev version.

robitalec commented 3 years ago

Thanks @wlandau. The new error message helps point me to double check the drake_plan() assignment, perfect.

Sorry about the confusion for the second note - in haste I swapped the name of the variable to check, but forgot that it is simply whatever the plan is named, passed to drake_config().

Much appreciated.