JuliaPluto / PlutoSliderServer.jl

Web server to run just the `@bind` parts of a Pluto.jl notebook
https://computationalthinking.mit.edu/
The Unlicense
130 stars 17 forks source link

Error when `export_directory` or `export_notebook` fails #73

Open theogf opened 2 years ago

theogf commented 2 years ago

Is there a way to know if some cells failed while running export_notebook or export_directory? When running PlutoSliderServer.jl on CI, it would be good to know if the build worked or not

filchristou commented 9 months ago

btw PlutoStaticHTML.jl already support this. I am not sure how easily the same solution can be integrated here though..

theogf commented 3 months ago

For what it's worth I have written my own small printing function that shows which notebooks failed and with which errors:

"""
Given a selection of notebooks, check individually for each notebook if there are 
any cells that errored.
If it is the case print out, for each notebook, the content of the failing cells
and the output messages.
"""
function check_for_failed_notebooks(result::NamedTuple)
  failed_notebooks = Dict{String, Vector}()
  # notebook session is a `NotebookSession` from PlutoSliderServer.jl.
  for notebook_session in result.notebook_sessions
    # Check for every notebook that no cell errored.
    # State is a large JSON style `Dict` containing all the informations about the ran notebook.
    # You can find the definition in Pluto.jl/src/webserver/Dynamic.jl/notebook_to_js.
    state = notebook_session.run.original_state
    errored_cells = findall(cell -> cell["errored"], state["cell_results"])
    isempty(errored_cells) && continue
    failed_notebooks[notebook_session.path] = [
      (input = state["cell_inputs"][id]["code"], output = state["cell_results"][id]["output"]["body"][:msg]) for
      id in sort(errored_cells; by = id -> findfirst(==(id), state["cell_order"]))
    ]
  end
  if !isempty(failed_notebooks)
    io = IOBuffer()
    for (key, cells) in pairs(failed_notebooks)
      printstyled(IOContext(io, :color => true), "$key:\n"; bold = true, color = :green, underline = true)
      for (input, output) in cells
        printstyled(IOContext(io, :color => true), "• $input"; color = :blue)
        print(io, " => ")
        printstyled(IOContext(io, :color => true), "$output\n"; color = :red)
      end
      println(io)
    end
    error_msgs = String(take!(io))
    error(
      "The following Pluto notebook",
      length(failed_notebooks) > 1 ? "s" : "",
      " failed to run successfully: $(keys(failed_notebooks))\n\n",
      error_msgs,
    )
  end
end

This is to be passed to export_directory as the on_ready kwarg.