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.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
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