Replies: 8 comments 2 replies
-
This is a great question, though more of a Julia issue than something specific to Oceananigans! However, there is an off-chance that there is some feature we could implement to make this easier for people. Note that terminals also have line limits and its a problem for people working in the terminal too. I use the silly but practical solution of reducing my font size and re-executing code until l can see the top of the error message. However, there are probably other solutions. I wrote up a little example to experiment: using Oceananigans
grid = RectilinearGrid(size=(1, 1, 1), extent=(1, 1, 1))
model = HydrostaticFreeSurfaceModel(; grid)
simulation = Simulation(model, Δt=1.0)
bad_callback(sim) = error("Why did you write such a bad callback?")
simulation.callbacks[:error] = Callback(bad_callback)
run!(simulation) Some hunting on google returned this thread: https://discourse.julialang.org/t/redirect-output-and-error-to-a-file/58908/3 One option is to pipe to a file with the terminal utility $ julia --project | tee out.txt All output generated thereafter is written to It looks it may also be possible to use the Julia module https://docs.julialang.org/en/v1/manual/stacktraces/ With the above example I found julia> err, st = try
run!(simulation)
catch err
err, stacktrace()
end
[ Info: Initializing simulation...
(ErrorException("Why did you write such a bad callback?"), Base.StackTraces.StackFrame[top-level scope at REPL[2]:4, eval at boot.jl:360 [inlined], eval_user_input(ast::Any, backend::REPL.REPLBackend) at REPL.jl:139, repl_backend_loop(backend::REPL.REPLBackend) at REPL.jl:200, start_repl_backend(backend::REPL.REPLBackend, consumer::Any) at REPL.jl:185, run_repl(repl::REPL.AbstractREPL, consumer::Any; backend_on_current_task::Bool) at REPL.jl:317, run_repl(repl::REPL.AbstractREPL, consumer::Any) at REPL.jl:305, (::Base.var"#875#877"{Bool, Bool, Bool})(REPL::Module) at client.jl:387, #invokelatest#2 at essentials.jl:708 [inlined], invokelatest at essentials.jl:706 [inlined], run_main_repl(interactive::Bool, quiet::Bool, banner::Bool, history_file::Bool, color_set::Bool) at client.jl:372, exec_options(opts::Base.JLOptions) at client.jl:302, _start() at client.jl:485])
julia> st
13-element Vector{Base.StackTraces.StackFrame}:
top-level scope at REPL[2]:4
eval at boot.jl:360 [inlined]
eval_user_input(ast::Any, backend::REPL.REPLBackend) at REPL.jl:139
repl_backend_loop(backend::REPL.REPLBackend) at REPL.jl:200
start_repl_backend(backend::REPL.REPLBackend, consumer::Any) at REPL.jl:185
run_repl(repl::REPL.AbstractREPL, consumer::Any; backend_on_current_task::Bool) at REPL.jl:317
run_repl(repl::REPL.AbstractREPL, consumer::Any) at REPL.jl:305
(::Base.var"#875#877"{Bool, Bool, Bool})(REPL::Module) at client.jl:387
#invokelatest#2 at essentials.jl:708 [inlined]
invokelatest at essentials.jl:706 [inlined]
run_main_repl(interactive::Bool, quiet::Bool, banner::Bool, history_file::Bool, color_set::Bool) at client.jl:372
exec_options(opts::Base.JLOptions) at client.jl:302
_start() at client.jl:485julia> err, st = try
run!(simulation)
catch err
err, stacktrace()
end
[ Info: Initializing simulation...
(ErrorException("Why did you write such a bad callback?"), Base.StackTraces.StackFrame[top-level scope at REPL[2]:4, eval at boot.jl:360 [inlined], eval_user_input(ast::Any, backend::REPL.REPLBackend) at REPL.jl:139, repl_backend_loop(backend::REPL.REPLBackend) at REPL.jl:200, start_repl_backend(backend::REPL.REPLBackend, consumer::Any) at REPL.jl:185, run_repl(repl::REPL.AbstractREPL, consumer::Any; backend_on_current_task::Bool) at REPL.jl:317, run_repl(repl::REPL.AbstractREPL, consumer::Any) at REPL.jl:305, (::Base.var"#875#877"{Bool, Bool, Bool})(REPL::Module) at client.jl:387, #invokelatest#2 at essentials.jl:708 [inlined], invokelatest at essentials.jl:706 [inlined], run_main_repl(interactive::Bool, quiet::Bool, banner::Bool, history_file::Bool, color_set::Bool) at client.jl:372, exec_options(opts::Base.JLOptions) at client.jl:302, _start() at client.jl:485])
julia> st
13-element Vector{Base.StackTraces.StackFrame}:
top-level scope at REPL[2]:4
eval at boot.jl:360 [inlined]
eval_user_input(ast::Any, backend::REPL.REPLBackend) at REPL.jl:139
repl_backend_loop(backend::REPL.REPLBackend) at REPL.jl:200
start_repl_backend(backend::REPL.REPLBackend, consumer::Any) at REPL.jl:185
run_repl(repl::REPL.AbstractREPL, consumer::Any; backend_on_current_task::Bool) at REPL.jl:317
run_repl(repl::REPL.AbstractREPL, consumer::Any) at REPL.jl:305
(::Base.var"#875#877"{Bool, Bool, Bool})(REPL::Module) at client.jl:387
#invokelatest#2 at essentials.jl:708 [inlined]
invokelatest at essentials.jl:706 [inlined]
run_main_repl(interactive::Bool, quiet::Bool, banner::Bool, history_file::Bool, color_set::Bool) at client.jl:372
exec_options(opts::Base.JLOptions) at client.jl:302
_start() at client.jl:485 I'm not sure how this can be turned into something useful, but perhaps its a starting point. It may even be possible (though probably a bit futuristic) to implement a kwarg in |
Beta Was this translation helpful? Give feedback.
-
This is helpful - thanks Greg. It's good to have some options when unable to find the error messages during debugging! |
Beta Was this translation helpful? Give feedback.
-
Probably the best solution right now is to re-run in a terminal. But there is still some improvement to be had since that option requires re-compilation, so will slow development down. If you find any VSCode-specific information please post here. I wonder if VSCode can pipe stdout to file? Also we may want to convert this to a discussion, what do you think? |
Beta Was this translation helpful? Give feedback.
-
Well, the
then julia> @info "hi tim"
[ Info: hi tim
julia> error("what the heck")
ERROR: what the heck
Stacktrace:
[1] error(s::String)
@ Base ./error.jl:33
[2] top-level scope
@ REPL[2]:1 yields the file
There's probably some setting to produce simple i/o even at the REPL though. |
Beta Was this translation helpful? Give feedback.
-
Would something like https://github.com/BioTurboNick/AbbreviatedStackTraces.jl be a good approach to abbreviate the kernelabstraction stacktraces? |
Beta Was this translation helpful? Give feedback.
-
VS Code and most other terminals have an setting for the output buffer size. I set mine to 10000 (default is 1000) because I was getting some extra-long errors recently and couldn't see the important part of the stacktrace. For VS Code, open |
Beta Was this translation helpful? Give feedback.
-
To get around the terminal not being long enough I use InteractiveErrors.jl which gives you a much shorter initial message and lets you copy the whole thing to the clipboard instead of printing it out. So I usually do that and then paste it into a file. |
Beta Was this translation helpful? Give feedback.
-
For interactive debugging AbbreviatedStackTraces.jl and InteractiveErrors.jl look great. For file output LoggingExtras.jl lets you keep terminal logging with a custom logger like log_filepath = joinpath(output_dir, "training.log")
TeeLogger(
OceananigansLogger(),
MinLevelLogger(FileLogger(log_filepath), Logging.Info)
) |> global_logger Could be used to provide stdout and stderr files. |
Beta Was this translation helpful? Give feedback.
-
Can we output the super long message that appears on the REPL when running the model to a text file so that the actual key error message will not be overwhelmed by the other irrelevant stuff? Something like the default option in MITgcm with the STDOUT/STDERR files. For those who run on a terminal, this is probably fine because they can scroll up (assuming they don't miss it!) but in VScode there's a limit on how much you can output.
Beta Was this translation helpful? Give feedback.
All reactions