Skip to content

Fix DAG export bug #223

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
May 30, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/R-CMD-check.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ jobs:
REDCAPTIDIER_LONGITUDINAL_DAG_API: ${{ secrets.REDCAPTIDIER_LONGITUDINAL_DAG_API }}
REDCAPTIDIER_MIXED_STRUCTURE_API: ${{ secrets.REDCAPTIDIER_MIXED_STRUCTURE_API }}
REDCAPTIDIER_MDC_API: ${{ secrets.REDCAPTIDIER_MDC_API }}
REDCAPTIDIER_DAG_ACCESS_API: ${{ secrets.REDCAPTIDIER_DAG_ACCESS_API }}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Annoying to add a whole other database and secret for this but c'est la vie.

steps:
- name: Update Ubuntu, Install cURL Headers, add Libraries
run: |
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/test-coverage.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ jobs:
REDCAPTIDIER_DAG_API: ${{ secrets.REDCAPTIDIER_DAG_API }}
REDCAPTIDIER_LONGITUDINAL_DAG_API: ${{ secrets.REDCAPTIDIER_LONGITUDINAL_DAG_API }}
REDCAPTIDIER_MDC_API: ${{ secrets.REDCAPTIDIER_MDC_API }}
REDCAPTIDIER_DAG_ACCESS_API: ${{ secrets.REDCAPTIDIER_DAG_ACCESS_API }}
steps:
- name: Update Ubuntu, Install cURL Headers, add Libraries
run: |
Expand Down
12 changes: 7 additions & 5 deletions R/read_redcap.R
Original file line number Diff line number Diff line change
Expand Up @@ -204,11 +204,13 @@ read_redcap <- function(redcap_uri,
# If DAGs detected and requested in label format, trigger an API call and
# update column data for redcap_data_access_group
if ("redcap_data_access_group" %in% names(db_data) && raw_or_label != "raw") {
dag_data <- redcap_dag_read(
redcap_uri = redcap_uri,
token = token,
verbose = !suppress_redcapr_messages
)$data
dag_data <- try_redcapr({
redcap_dag_read(
redcap_uri = redcap_uri,
token = token,
verbose = !suppress_redcapr_messages
)
})

db_data <- update_dag_cols(
data = db_data,
Expand Down
33 changes: 24 additions & 9 deletions R/utils.R
Original file line number Diff line number Diff line change
Expand Up @@ -805,19 +805,22 @@ try_redcapr <- function(expr, call = caller_env()) {
"i" = "URI: `{condition$redcap_uri}`"
)
condition$class <- c("cannot_post", condition$class)
} else if (!is.null(out$outcome_message) && str_detect(
out$outcome_message,
"You must have 'API Export' privileges and 'Data Access Groups' privileges"
)
) {
condition$info <- c(
"!" = "You do not have sufficient privileges to export data access groups.",
"i" = "Set `export_data_access_groups = FALSE` if you do not intend to export data access groups."
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perfect!

)
condition$class <- c("dag_access_error", condition$class)
condition$parent <- append_outcome_message(quo, out$outcome_message)
} else {
condition$class <- c("unexpected_error", condition$class)

if (!is.null(out$outcome_message)) {
# Throw error containing outcome message and attach that as the parent
# Get the name of the function called inside try_redcapr so it can be mentioned in the error message
calling_fn <- quo_get_expr(quo)
# Handle case where try_redcapr had multiline expr
if (inherits(calling_fn, "{")) {
calling_fn <- calling_fn[[2]]
}

condition$parent <- catch_cnd(abort(out$outcome_message, call = calling_fn))
condition$parent <- append_outcome_message(quo, out$outcome_message)
}
}
cli_abort(
Expand All @@ -834,6 +837,18 @@ try_redcapr <- function(expr, call = caller_env()) {
out$data
}

append_outcome_message <- function(quo, outcome_message) {
# Throw error containing outcome message and attach that as the parent
# Get the name of the function called inside try_redcapr so it can be mentioned in the error message
calling_fn <- quo_get_expr(quo)
# Handle case where try_redcapr had multiline expr
if (inherits(calling_fn, "{")) {
calling_fn <- calling_fn[[2]]
}

catch_cnd(abort(outcome_message, call = calling_fn))
}


#' @title
#' Check whether a REDCap database has repeat forms
Expand Down
15 changes: 15 additions & 0 deletions tests/testthat/test-read_redcap.R
Original file line number Diff line number Diff line change
Expand Up @@ -755,3 +755,18 @@ test_that("update_dag_cols() works for haven labels", {
expect_equal(out$redcap_data_access_group, expected_vec)
expect_equal(out, expected_out)
})

test_that("read_redcap() handles insufficient DAG access", {
read_redcap(
Sys.getenv("REDCAP_URI"),
Sys.getenv("REDCAPTIDIER_DAG_ACCESS_API")
) |>
expect_error(class = "dag_access_error")

read_redcap(
Sys.getenv("REDCAP_URI"),
Sys.getenv("REDCAPTIDIER_DAG_ACCESS_API"),
export_data_access_groups = FALSE
) |>
expect_no_error()
})
4 changes: 4 additions & 0 deletions utility/cli_message_examples.R
Original file line number Diff line number Diff line change
Expand Up @@ -151,3 +151,7 @@ read_redcap(Sys.getenv("REDCAP_URI"), Sys.getenv("REDCAPTIDIER_CLASSIC_API")) %>
# missing data codes

read_redcap(redcap_uri, Sys.getenv("REDCAPTIDIER_MDC_API"))

# No DAG export access

read_redcap(Sys.getenv("REDCAP_URI"), Sys.getenv("REDCAPTIDIER_DAG_ACCESS_API"))
26 changes: 19 additions & 7 deletions utility/cli_message_examples_reprex.md
Original file line number Diff line number Diff line change
Expand Up @@ -112,8 +112,8 @@ read_redcap(redcap_uri, classic_token, export_survey_fields = 123)

read_redcap(redcap_uri, classic_token, export_survey_fields = c(TRUE, TRUE))
#> Error in `read_redcap()`:
#> ✖ You've supplied `TRUE` and `TRUE` for `export_survey_fields` which is
#> not a valid value
#> ✖ You've supplied `TRUE` `TRUE` for `export_survey_fields` which is not
#> a valid value
#> ! Must have length 1, but has length 2

## suppress_redcapr_messages
Expand All @@ -126,8 +126,8 @@ read_redcap(redcap_uri, classic_token, suppress_redcapr_messages = 123)

read_redcap(redcap_uri, classic_token, suppress_redcapr_messages = c(TRUE, TRUE))
#> Error in `read_redcap()`:
#> ✖ You've supplied `TRUE` and `TRUE` for `suppress_redcapr_messages`
#> which is not a valid value
#> ✖ You've supplied `TRUE` `TRUE` for `suppress_redcapr_messages` which is
#> not a valid value
#> ! Must have length 1, but has length 2

# data access groups
Expand Down Expand Up @@ -255,7 +255,7 @@ withr::with_tempdir({
})
#> Error:
#> ✖ File
#> ''/private/var/folders/qc/mmjjyjq50530z9r_7mfqcqfhxkkk67/T/Rtmph4LQ3Z/filee5aa7b9bea48/temp.csv''
#> ''/private/var/folders/9c/k1m0bzys7gb1v32g86hfn5sn5k86h1/T/RtmpQCmzPP/file1411b189a9c52/temp.csv''
#> already exists.
#> ℹ Overwriting files is disabled by default. Set `overwrite = TRUE` to overwrite
#> existing file.
Expand Down Expand Up @@ -296,7 +296,7 @@ withr::with_tempdir({
write_redcap_xlsx(file = filepath)
})
#> Warning in write_redcap_xlsx(., file = filepath): ! No extension provided for `file`:
#> '/private/var/folders/qc/mmjjyjq50530z9r_7mfqcqfhxkkk67/T/Rtmph4LQ3Z/filee5aa11455c98/temp'
#> '/private/var/folders/9c/k1m0bzys7gb1v32g86hfn5sn5k86h1/T/RtmpQCmzPP/file1411b1319086f/temp'
#> ℹ The extension '.xlsx' will be appended to the file name.

# Printed supertibble
Expand Down Expand Up @@ -338,6 +338,18 @@ read_redcap(redcap_uri, Sys.getenv("REDCAPTIDIER_MDC_API"))
#> 1 form_1 Form 1 <tibble [3 × 9]> <tibble> nonrepeat…
#> # ℹ 5 more variables: data_rows <int>, data_cols <int>, data_size <lbstr_by>,
#> # data_na_pct <formttbl>, form_complete_pct <formttbl>

# No DAG export access

read_redcap(Sys.getenv("REDCAP_URI"), Sys.getenv("REDCAPTIDIER_DAG_ACCESS_API"))
#> Error in `read_redcap()`:
#> ✖ The REDCapR export operation was not successful.
#> ! You do not have sufficient privileges to export data access groups.
#> ℹ Set `export_data_access_groups = FALSE` if you do not intend to export data
#> access groups.
#> Caused by error in `redcap_dag_read()`:
#> ! The REDCapR read/export operation was not successful. The error message was:
#> ERROR: Insufficient user privileges: You must have 'API Export' privileges and 'Data Access Groups' privileges in the project.
```

<sup>Created on 2024-10-16 with [reprex v2.1.0](https://reprex.tidyverse.org)</sup>
<sup>Created on 2025-05-30 with [reprex v2.1.0](https://reprex.tidyverse.org)</sup>