Skip to content

Commit

Permalink
Log stacktraces
Browse files Browse the repository at this point in the history
  • Loading branch information
visr committed Jul 23, 2024
1 parent 0a46892 commit a959c4f
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 14 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -154,3 +154,6 @@ playground/output
# Ruff
.ruff_cache
.teamcity/.idea/

# https://github.com/Deltares/Ribasim/issues/1652
ribasim_qgis/tests/data/database.gpkg
39 changes: 27 additions & 12 deletions core/src/main.jl
Original file line number Diff line number Diff line change
Expand Up @@ -40,23 +40,38 @@ function main(toml_path::AbstractString)::Cint
@warn "The Ribasim version in the TOML config file does not match the used Ribasim CLI version." config.ribasim_version cli.ribasim_version
end
@info "Starting a Ribasim simulation." cli.ribasim_version starttime endtime
model = run(config)

if successful_retcode(model)
log_bottlenecks(model; converged = true)
@info "The model finished successfully"
return 0
else
log_bottlenecks(model; converged = false)
t = datetime_since(model.integrator.t, starttime)
retcode = model.integrator.sol.retcode
@error """The model exited at model time $t with return code $retcode.
See https://docs.sciml.ai/DiffEqDocs/stable/basics/solution/#retcodes"""

try
model = run(config)

if successful_retcode(model)
log_bottlenecks(model; converged = true)
@info "The model finished successfully."
return 0
else
# OrdinaryDiffEq doesn't error on e.g. convergence failure,
# but we want a non-zero exit code in that case.
log_bottlenecks(model; converged = false)
t = datetime_since(model.integrator.t, starttime)
retcode = model.integrator.sol.retcode
@error """The model exited at model time $t with return code $retcode.
See https://docs.sciml.ai/DiffEqDocs/stable/basics/solution/#retcodes"""
return 1
end

catch
# Both validation errors that we throw and unhandled exceptions are caught here.
# To make it easier to find the cause, log the stacktrace to the terminal and log file.
stack = current_exceptions()
Base.invokelatest(Base.display_error, stack)
Base.invokelatest(Base.display_error, io, stack)
return 1
end
end
end
catch
# If it fails before we get to setup the logger, we can't log to a file.
# This happens if e.g. the config is invalid.
Base.invokelatest(Base.display_error, current_exceptions())
return 1
end
Expand Down
27 changes: 25 additions & 2 deletions core/test/main_test.jl
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@

@testitem "toml_path" begin
@testitem "main output" begin
using IOCapture: capture
import TOML
using Ribasim: Config, results_path

model_path = normpath(@__DIR__, "../../generated_testmodels/basic/")
toml_path = normpath(model_path, "ribasim.toml")
Expand All @@ -26,3 +26,26 @@
@test occursin("version in the TOML config file does not match", output)
@test occursin("Info: Convergence bottlenecks in descending order of severity:", output)
end

@testitem "main error logging" begin
using IOCapture: capture
import TOML
using Ribasim: Config, results_path

model_path = normpath(@__DIR__, "../../generated_testmodels/invalid_edge_types/")
toml_path = normpath(model_path, "ribasim.toml")

@test ispath(toml_path)
(; value, output) = capture() do
Ribasim.main(toml_path)
end
@test value == 1

# Stacktraces should be written to both the terminal and log file.
@test occursin("\nStacktrace:\n", output)
config = Config(toml_path)
log_path = results_path(config, "ribasim.log")
@test ispath(log_path)
log_str = read(log_path, String)
@test occursin("\nStacktrace:\n", log_str)
end

0 comments on commit a959c4f

Please sign in to comment.