Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Exception thrown inside Base.show(::IO, x) can cause an exception to leak a log message. #56889

Open
NHDaly opened this issue Dec 22, 2024 · 0 comments
Labels
error handling Handling of exceptions by Julia or the user logging The logging framework

Comments

@NHDaly
Copy link
Member

NHDaly commented Dec 22, 2024

Julia has a nice feature built in to its logging package: An exception thrown while constructing a log message is captured and printed, rather than allowing it to throw, so that a bug in a log statement cannot break a process that would otherwise have succeeded without the log.

This is especially nice for allowing people to enable DEBUG logging without having to worry that it might cause unexpected crashes, since the debug-log-level is not often tested.

However, there is currently a gap: The try/catch is only around constructing the message, not printing it.

Consider these two examples:

julia> begin
           # As expected, this exception will be trapped & printed
           @info throw(2)
           # So we will also get to see this print-line:
           println("~~~~~ ALL DONE ~~~~~~~~")
       end
┌ Error: Exception while generating log record in module Main at REPL[25]:3
│   exception = (2, Union{Ptr{Nothing}, Base.InterpreterIP}[Ptr{Nothing} @0x0000000100e96d67, Ptr{Nothing} @0x0000000100e88ae3, Ptr{Nothing} @0x0000000100ea3bcb, Ptr{Nothing} @0x0000000100ea214b, Ptr{Nothing} @0x0000000100ea2667, Ptr{Nothing} @0x0000000100ea2a0f, Base.InterpreterIP in top-level CodeInfo for Main at statement 30, Ptr{Nothing} @0x0000000100ebb3ab, Ptr{Nothing} @0x0000000100ebb173, Ptr{Nothing} @0x0000000100ebb173    Ptr{Nothing} @0x0000000138a6202b, Ptr{Nothing} @0x0000000100e88ae3, Ptr{Nothing} @0x0000000100e9780f, Ptr{Nothing} @0x0000000138f7814f, Ptr{Nothing} @0x0000000138a881a7, Ptr{Nothing} @0x0000000138f799bf, Ptr{Nothing} @0x0000000138d06137, Ptr{Nothing} @0x0000000100e88ae3, Ptr{Nothing} @0x0000000100ee8693, Ptr{Nothing} @0x0000000100ee8587])
└ @ Main REPL[25]:3
~~~~~ ALL DONE ~~~~~~~~
julia> begin
           # Unexpectedly, the execption thrown while printing `Foo()` escapes
           @info Foo()
           # So we never reach this line! :'(
           println("~~~~~ ALL DONE ~~~~~~~~")
       end
ERROR: oh no
Stacktrace:
  [1] error(s::String)
    @ Base ./error.jl:35
  [2] show(::IOBuffer, ::Foo)
    @ Main ./REPL[27]:1
  [3] print(io::IOBuffer, x::Foo)
    @ Base ./strings/io.jl:35
  [4] print_to_string(xs::Foo)
    @ Base ./strings/io.jl:148
  [5] string(xs::Foo)
    @ Base ./strings/io.jl:189
  [6] 
    @ Logging ~/builds/julia-RAI/usr/share/julia/stdlib/v1.10/Logging/src/ConsoleLogger.jl:119
  [7] 
    @ Logging ~/builds/julia-RAI/usr/share/julia/stdlib/v1.10/Logging/src/ConsoleLogger.jl:106
  [8] invokelatest(::Any, ::Any, ::Vararg{Any}; kwargs::@Kwargs{})
    @ Base ./essentials.jl:892
  [9] invokelatest(::Any, ::Any, ::Vararg{Any})
    @ Base ./essentials.jl:889
 [10] macro expansion
    @ logging.jl:377 [inlined]
 [11] top-level scope
    @ REPL[28]:3
Some type information was truncated. Use `show(err)` to see complete types.

This is because the try/catch is put around the construction of the message variable, but not while calling Base.CoreLogging.handle_message.

Can we extend the try/catch to also wrap handle_message? Is there any reason we don't do this currently?
Thanks!

@NHDaly NHDaly added the logging The logging framework label Dec 22, 2024
@nsajko nsajko added the error handling Handling of exceptions by Julia or the user label Dec 23, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
error handling Handling of exceptions by Julia or the user logging The logging framework
Projects
None yet
Development

No branches or pull requests

2 participants