rstudio / plumber

Turn your R code into a web API.
https://www.rplumber.io
Other
1.38k stars 256 forks source link

Should mounted routers inherit error/404/serializer/etc from parent mount if non have been set? #879

Open jwebbsoma opened 1 year ago

jwebbsoma commented 1 year ago

System details

─ Session info ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
 setting  value
 version  R version 4.2.1 (2022-06-23 ucrt)
 os       Windows 10 x64 (build 19044)
 system   x86_64, mingw32
 ui       RStudio
 language (EN)
 collate  English_United States.utf8
 ctype    English_United States.utf8
 tz       America/Chicago
 date     2022-09-09
 rstudio  2022.02.0+443 Prairie Trillium (desktop)
 pandoc   NA

! package     * version    date (UTC) lib source
plumber     * 1.1.0      2021-03-24 [?] CRAN (R 4.2.0)

Example application or steps to reproduce the problem

plumber.R:

#* @get /trouble
function(req) {
  stop("I'm an error in plumber.R!")
}

#* @plumber
function(pr) {
  pr %>%
    pr_mount("/data", plumb("./controllers/data.R")) %>%
    pr_get("/simple", function() stop("I'm an error!")) %>%
    pr_set_error(function(req, res, err){
      print(err)
      res$status <- 500
      list(error = "An error occurred. Please contact your administrator.")}) %>%
    pr_set_serializer(serializer_unboxed_json(na="null", null="null", force=TRUE, digits=15))

}

./controllers/data.R:

#* @get /columns
getColumns = function(req) {
  stop("I'm an error in dataController!")
  # ...
}

Describe the problem in detail

Trying to setup a global error handler and it appears to not be working for any endpoints defined in a mounted file. Running the above plumber code will result in "/simple" and "/trouble" returning the custom error message but "/data/columns" does not. Is there something special I need to be doing for mounted files to be included with the custom error handler?

schloerke commented 1 year ago

Currently all mounted routers behave pretty independently from their parent router.

For now, you'll need to add the custom behavior manually

#* @plumber
function(pr) {
  err_func <- function(req, res, err) {
    print(err)
    res$status <- 500
    list(error = "An error occurred. Please contact your administrator.")
  }
  data_pr <- 
    plumb("./controllers/data.R") %>%
    pr_set_error(err_func)

  pr %>%
    pr_mount("/data", data_pr) %>%
    pr_get("/simple", function() stop("I'm an error!")) %>%
    pr_set_error(err_func) %>%
    pr_set_serializer(serializer_unboxed_json(na="null", null="null", force=TRUE, digits=15))
}
schloerke commented 1 year ago

If pr_merge() was implemented, I believe this confusion would go away. Keeping open until pr_merge() is implemented.

LeeMendelowitz commented 4 months ago

Related: https://github.com/rstudio/plumber/issues/815