function foo(x)
error("error on line $(@__LINE__)")
end
#-
foo(42)
I get an error which does not actually show a stacktrace of where the exception was raised
julia> Literate.notebook("stacktrace.jl")
[ Info: generating notebook from `~/Julia/Literate/stacktrace.jl`
[ Info: executing notebook `stacktrace.ipynb`
┌ Error: error when executing notebook based on input file: `~/Julia/Literate/stacktrace.jl`
└ @ Literate ~/Julia/Literate/src/Literate.jl:667
ERROR: LoadError: error on line 2
in expression starting at string:1
when executing the following code block in file `~/Julia/Literate/stacktrace.jl`
```julia
foo(42)
The stacktrace traces back to this `error` call: https://github.com/fredrikekre/Literate.jl/blob/42f39411cd5ebc22fc934161447c42548fe29e6f/src/Literate.jl#L785-L792
With this patch you get something like the following (which could be much longer if the error thrown is deep in some dependency, which is the information you would want):
Now, I don't yet quite have a good idea of how to do this well, so opening this for discussion. This was just a side tangent when working on a notebook. A few notes though:
* The simple option (least amount of code modified) would actually be to `sprintf` the backtrace into `error`. However, returning a custom exception object seems like the more correct thing to do.
* The `@error` from the parent function seems actually redundant.
* I noticed that by using `include_string`, any error I think gets wrapped in `LoadError` (but this does not seem to be documented). It also adds a bunch of things into the stacktrace which are hard to get rid of.
* It's sorta confusing that we print two stacktraces.. but it's sorta the right thing to do. Unless we can somehow do some `rethrow`-type magic..
Currently, suppose I have a file like
I get an error which does not actually show a stacktrace of where the exception was raised
Stacktrace: [1] error(s::String) @ Base ./error.jl:33 [2] execute_block(sb::Module, block::String; inputfile::String) @ Literate ~/Julia/Literate/src/Literate.jl:785 [3] execute_notebook(nb::Dict{Any, Any}; inputfile::String) @ Literate ~/Julia/Literate/src/Literate.jl:683 [4] (::Literate.var"#36#38"{Dict{String, Any}})() @ Literate ~/Julia/Literate/src/Literate.jl:664 [5] cd(f::Literate.var"#36#38"{Dict{String, Any}}, dir::String) @ Base.Filesystem ./file.jl:106 [6] jupyter_notebook(chunks::Vector{Literate.Chunk}, config::Dict{String, Any}) @ Literate ~/Julia/Literate/src/Literate.jl:663 [7] notebook(inputfile::String, outputdir::String; config::Dict{Any, Any}, kwargs::Base.Iterators.Pairs{Union{}, Union{}, Tuple{}, NamedTuple{(), Tuple{}}}) @ Literate ~/Julia/Literate/src/Literate.jl:600 [8] notebook (repeats 2 times) @ ~/Julia/Literate/src/Literate.jl:596 [inlined] [9] top-level scope @ REPL[6]:1
julia> Literate.notebook("stacktrace.jl") [ Info: generating notebook from
~/Julia/Literate/stacktrace.jl
[ Info: executing notebookstacktrace.ipynb
┌ Error: error when executing notebook based on input file:~/Julia/Literate/stacktrace.jl
└ @ Literate ~/Julia/Literate/src/Literate.jl:667 ERROR: Literate.EvalException: LoadError when executing code in: ~/Julia/Literate/stacktrace.jl LoadError: error on line 2 Stacktrace: [1] error(s::String) @ Base ./error.jl:33 [2] foo(x::Int64) @ Main.##257 ./string:2 [3] top-level scope @ string:1 [4] eval @ ./boot.jl:360 [inlined] [5] include_string(mapexpr::typeof(identity), mod::Module, code::String, filename::String) @ Base ./loading.jl:1094 [6] include_string (repeats 2 times) @ ./loading.jl:1104 [inlined] [7] #42 @ ~/Julia/Literate/src/Literate.jl:781 [inlined] [8] (::IOCapture.var"#3#5"{Core.TypeofBottom, Literate.var"#42#43"{Module, String}, Task, Pipe, Base.TTY, Base.TTY})() @ IOCapture ~/.julia/packages/IOCapture/g8FZl/src/IOCapture.jl:105 [9] with_logstate(f::Function, logstate::Any) @ Base.CoreLogging ./logging.jl:491 [10] with_logger @ ./logging.jl:603 [inlined] [11] capture(f::Literate.var"#42#43"{Module, String}; rethrow::Type, color::Bool) @ IOCapture ~/.julia/packages/IOCapture/g8FZl/src/IOCapture.jl:103 [12] execute_block(sb::Module, block::String; inputfile::String) @ Literate ~/Julia/Literate/src/Literate.jl:780 in expression starting at string:1Stacktrace: [1] execute_block(sb::Module, block::String; inputfile::String) @ Literate ~/Julia/Literate/src/Literate.jl:801 [2] execute_notebook(nb::Dict{Any, Any}; inputfile::String) @ Literate ~/Julia/Literate/src/Literate.jl:683 [3] (::Literate.var"#36#38"{Dict{String, Any}})() @ Literate ~/Julia/Literate/src/Literate.jl:664 [4] cd(f::Literate.var"#36#38"{Dict{String, Any}}, dir::String) @ Base.Filesystem ./file.jl:106 [5] jupyter_notebook(chunks::Vector{Literate.Chunk}, config::Dict{String, Any}) @ Literate ~/Julia/Literate/src/Literate.jl:663 [6] notebook(inputfile::String, outputdir::String; config::Dict{Any, Any}, kwargs::Base.Iterators.Pairs{Union{}, Union{}, Tuple{}, NamedTuple{(), Tuple{}}}) @ Literate ~/Julia/Literate/src/Literate.jl:600 [7] notebook (repeats 2 times) @ ~/Julia/Literate/src/Literate.jl:596 [inlined] [8] top-level scope @ REPL[2]:1