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
Handle errors in display functions more gracefully and isolate full html pages #285
Conversation
[The following discussion about formattable is obsolete...] So, the main reason is that this now works: #devtools::install_github("renkun-ken/formattable")
df <- data.frame(
id = 1:10,
name = c("Bob", "Ashley", "James", "David", "Jenny",
"Hans", "Leo", "John", "Emily", "Lee"),
age = c(28, 27, 30, 28, 29, 29, 27, 27, 31, 30),
grade = c("C", "A", "A", "C", "B", "B", "B", "A", "C", "C"),
test1_score = c(8.9, 9.5, 9.6, 8.9, 9.1, 9.3, 9.3, 9.9, 8.5, 8.6),
test2_score = c(9.1, 9.1, 9.2, 9.1, 8.9, 8.5, 9.2, 9.3, 9.1, 8.8),
final_score = c(9, 9.3, 9.4, 9, 9, 8.9, 9.25, 9.6, 8.8, 8.7),
registered = c(TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE),
stringsAsFactors = FALSE)
library(formattable)
f <- formattable(df, list(
age = color_tile("white", "orange"),
grade = formatter("span",
style = x ~ ifelse(x == "A", style(color = "green", font.weight = "bold"), NA)),
test1_score = normalize_bar("pink", 0.2),
test2_score = normalize_bar("pink", 0.2),
final_score = formatter("span",
style = x ~ style(color = ifelse(rank(-x) <= 3, "green", "gray")),
x ~ sprintf("%.2f (rank: %02d)", x, rank(-x))),
registered = formatter("span",
style = x ~ style(color = ifelse(x, "green", "red")),
x ~ icontext(ifelse(x, "ok", "remove"), ifelse(x, "Yes", "No")))
))
repr_html.htmlwidget <- function(x, ...){
htmlfile <- tempfile(fileext = ".html")
# save the widget to HTML
htmlwidgets::saveWidget(
widget = x,
file = htmlfile,
selfcontained = TRUE
)
html_string <- readChar(htmlfile, file.info(htmlfile)$size)
return(html_string)
}
repr_html.formattable <- function(x){
repr_html.htmlwidget(as.htmlwidget(x))
}
f -> will show a colored table.... The problem here was that x <- print(f)
str(x) shows that x has something... :-( |
IIRC, we ran into something that hides output deliberately by making |
If that's so, we really need to change this here, so that if |
Unfortunatelly, this does not tell what was the problem: 7d0dddc BTW, this would again be solved if we only use repr_text per default and no repr_html... -> IRkernel/IRdisplay#18 (comment) :-) |
I think #127 is the relevant issue. The object being displayed is a data table, for which it does make sense to have rich reprs, so it wouldn't be solved by not doing rich reprs for primitive types. |
CommManager also uses debug. i fixed it in a local branch so you don’t have to do anything |
hmm, the iframe has why? |
so if we can’t fix that one, let’s redo the history of this branch with my fixes and then merge it in. |
Not sure about #127, but the 7d0dddc is the commit... |
I've just built this: handle_value <- function(obj) {
data <- namedlist()
metadata <- namedlist()
# We have to check the return value of print if it is visible and use the last object
# which is visible to compute the output from. There are a few packages which use print()
# to convert itself to something else (and don't output anything to the console) and the
# returned obj is the printed again.
print_return <<- list(visible=TRUE, value=obj)
send_even_if_no_print <- FALSE
while(returned_obj$visible) {
data[['text/plain']] <- paste(capture.output(print_return <<- withVisible(print(print_return$value))), collapse = '\n')
if (returned_obj$visible) repr_even_if_no_print <- TRUE
}
obj <- print_return$value
# data.table has some logic which can't use invisible() and therfore overwrites print to not
# return anything
if (send_even_if_no_print || nchar(data[['text/plain']]) > 0) {
if (getOption('jupyter.rich_display')) {
for (mime in getOption('jupyter.display_mimetypes')) {
# Use withCallingHandlers as that shows the inner stacktrace:
# https://stackoverflow.com/questions/15282471/get-stack-trace-on-trycatched-error-in-r
# the tryCatch is still needed to prevent the error from showing
# up outside further up the stack :-/
tryCatch(withCallingHandlers({
r <- mime2repr[[mime]](obj)
if (!is.null(r)) {
data[[mime]] <- r
# Isolating full html pages (putting them in an iframe)
if (identical(mime, 'text/html')) {
if (grepl("<html.*>", r, ignore.case = TRUE)){
jupyter_debug("Found full html page: %s", strtrim(r, 100))
metadata[[mime]] <- list(isolated = TRUE)
}
}
}
}, error = handle_display_error),
error=function(x){})
}
}
jupyter_debug("Sending display_data: %s", paste(capture.output(str(data)), collapse = "\n"))
send_response('display_data', request, 'iopub', list(
data = data,
metadata = metadata))
}
} |
dude. ````r`. |
@flying-sheep Just do it, you have edit right ... Also: sorry :-) |
haha np, it’s just that i did it so many times already 😉 you could cherry-pick 2bd6643 to get my changes into this PR. |
76b8038
to
abb67d3
Compare
added my stuff and cherry picked your commit... I will do some tests here and then it would be nice if someone of you could do a last pass over the code and merge if everything looks ok. |
great! please post again once your side is ready |
abb67d3
to
dc9fb21
Compare
Ok, the earlier commit was borked... Anyway, I this now works:
|
a0d8a85
to
b3bd32b
Compare
} | ||
} | ||
}, error = handle_display_error), | ||
error=function(x){}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
code style: spaces around =
, space between ) {
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
will add a new commit for this... and s/"/'/g
...
Is there any way to avoid that? It seems likely to annoy people. |
what does “when adding a new column” mean here? |
library(data.table)
dat <- data.table(x1=1:10)
dat[, x2 := 1:10] # should not and does not print
dat # does not print anything but should
print(dat) # prints something IMO the fix for the printing must go into data.table itself: it already has a workaround for knit_print |
uh, i remember something about this. someone explained that in some issue here |
Ok, this is still borked :-( I will add tests... |
OK, good idea! |
data.table not printing after doing an assignment is referenced in this issue: Rdatatable/data.table#939 |
Ach damn, now I see that At least now data.table behaves as I think it should... E.g. it prints a html table. |
So, using the debugger in RStudio (we really want So IMO the solution is here to remove most of the stuff in this PR and implement a |
hey @JanSchulz: i rebased and squashed your commits in here then i fast-forwarded master to have the code style fixes and logging system. so if you want to continue working on this, you shoud do: git fetch origin
git checkout isolate_full_html
git reset --hard origin/isolate-full-html and continue from there. |
Argh, the commit messages are all off :-/ (you have code style, I have commit messages :-)) Ok, will make a PR which has all the fixes for the tracebacks and then throw in a commit for a |
Before, when one repr_xxx was raising an error, the complete display machinery was impacted and no output was displayed. Now only the specific output is omitted and a user friendly error message is shown on stderr and the stacktrace (up to now pretty useless because it just shows one line) is shown on the console.
Using withCallingHandlers gives a better stacktrace which shows the stacktrace up to the place where the error is raised. Unfortunately, the error is not caught, so wrap the thing in a tryCatch which just does nothing...
Before, we only showed the error message, but no stacktrace in the notebook. The stacktrace was shown in the console. Now it is shown in both. This is in line what the IPython kernel does. We also now only display the stacktrace for the method which does something wrong and not our internal execution stuff...
Indicate that full html pages should be isolated in an iframe. Check if the html is a complete document (contains html) and set the right metadata.
e83c0fd
to
1b7d757
Compare
So, updated with only the relevant commits. This seems to work in my test notebook, but somehow travis does not kick in here? |
oh yeah, damn, should have used |
close→reopen→tests pass→merge |
Great! |
indeed! thank you! |
Before, when one repr_xxx was raising an error, the complete display machinery
was impacted and no output was displayed. Now only the specific output is
omitted and a user friendly error message + stacktrace is shown on stderr and
on the console.
Also indicate that full html pages should be isolated. Full html pages should be
isolated in the frontend in an iframe. Check if the html is a complete document
(contains html) and set the right metadata.
Closes: IRkernel/IRdisplay#18
Closes: #284