Skip to content
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

Add a link to parse failure location to load_all() #282

Merged
merged 7 commits into from
Jun 25, 2024

Conversation

olivroy
Copy link
Contributor

@olivroy olivroy commented May 24, 2024

Currently, the message when load_all() fails contains too much information. It is also inefficient to navigate to the culprit line manually when cli offers a way to do this.

This PR suggests to rethrow the message created by parse() to include a clickable hyperlink.

So that the full path doesn't get printed.

  • Also get a clickable link to the exact failure location.

Before:
image

This PR:
image

I also verified that this works when using pkgload with a path that is not "." and the link works perfectly!

I have modified traceback() in my .Rprofile to do just that, and it works really well! https://fosstodon.org/@olivroy/112441527899383725

Considerations

  • Only try to do this when the culprit is parse(). I don't know if other cases are possible. I will happily remove this condition if it is redundant.
  • Would be broken if parse() changed the way it does things (i.e. if the filename was not the first thing in the error message). However, regular CI should catch that pretty easily in advance and adjustments to pkgload could be made before the release of a new version of R.
  • I added an "At" before the path (for readability). I like it, but it may not fit well with internationalization. Also, does R support right to left text rendering, it may not work as expected in this case. I may remove the "At"

image

Note that I have been using pkgload with this PR for the past 2 weeks, and it is a significant speed improvement to my (careless) workflow to fix issues faster.

@olivroy olivroy changed the title Rethrow base R message when load_all() failed to parse. Rethrow base R message when load_all() failed to parse to add a link to parse failure May 24, 2024
@olivroy olivroy changed the title Rethrow base R message when load_all() failed to parse to add a link to parse failure Add a link to parse failure location to load_all() May 24, 2024
@lionel-
Copy link
Member

lionel- commented Jun 4, 2024

I'll be doing some package work during June and will look at this.

By the way you can also use rlang::global_handle() in your RProfile to get rlang backtraces for all errors.

R/source.R Outdated Show resolved Hide resolved
@olivroy
Copy link
Contributor Author

olivroy commented Jun 4, 2024

Thanks for the tip!

@olivroy
Copy link
Contributor Author

olivroy commented Jun 19, 2024

By the way you can also use rlang::global_handle() in your RProfile to get rlang backtraces for all errors.

I have been using it and it seems to clash with the RStudio debugger. Have you had this issue before?

@lionel-
Copy link
Member

lionel- commented Jun 20, 2024

I have been using it and it seems to clash with the RStudio debugger. Have you had this issue before?

In what way?

@olivroy
Copy link
Contributor Author

olivroy commented Jun 21, 2024

Oh never mind, the warning I get comes from loading twice my Rprofile containing global_entrace(). the warning just says that it is already enabled

R/source.R Outdated
@@ -13,7 +13,33 @@ source_many <- function(files, encoding = "UTF-8", envir = parent.frame()) {
source_one(file, encoding, envir = envir),
error = function(cnd) {
path <- file.path(basename(dirname(file)), basename(file))
msg <- paste0("Failed to load {.file {path}}")
is_parse_error <- tryCatch(identical(as.character(cnd$call[1]), "parse"), error = function(e) FALSE)
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
is_parse_error <- tryCatch(identical(as.character(cnd$call[1]), "parse"), error = function(e) FALSE)
is_parse_error <- is_call(cnd$call, "parse")

Copy link
Member

Choose a reason for hiding this comment

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

hmm I don't particularly like that this is assuming:

  • parse() corresponds to base::parse() and not some other user-defined function.
  • parse() failed inside source() and not in the user code. Admittedly this would be an odd thing to do, but that's still an ambiguity.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Do you mean the check?

I just wanted to add a condition on whether the error is a parsing to avoid fiddling with the message in other situations.

I have never encountered other types of errors than this one with load_all()

Copy link
Member

Choose a reason for hiding this comment

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

I understand, I'm just uncomfortable with this sort of ambiguity in such a low level tool. The new error message does seem better but the old one is not that bad

Copy link
Member

Choose a reason for hiding this comment

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

Clickable links would be great though

Copy link
Member

Choose a reason for hiding this comment

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

Another problem is that these messages could be translated so the regexp hot-patching is not reliable.

Copy link
Member

Choose a reason for hiding this comment

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

Though we can assume the file path is always at the beginning of the message I guess.

Another issue is that we should keep the file name in the parent error as is for other sources of errors, so it's clickable.

By the way replacing the message field of foreign conditions is not reliable because there might be (now or in the future) a conditionMessage() method.

I pushed a few changes to take care of these concerns.

@lionel- lionel- merged commit dfd3846 into r-lib:main Jun 25, 2024
13 checks passed
@lionel-
Copy link
Member

lionel- commented Jun 25, 2024

Thanks! It will be helpful to be able to click on these parse failure locations.

@olivroy
Copy link
Contributor Author

olivroy commented Jun 25, 2024

Thanks for finishing it! I think folks will like this! And for your explanations, very helpful

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants