5

I thought panic! stops everything in Rust, but if I panic! in an Iron route handler function it does not stop the whole server. Instead, it just displays the panic message.

Is it the "normal" behavior of panic!?

I'm not posting my actual code because I don't think it's useful here, but I can add it if required.

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
rap-2-h
  • 30,204
  • 37
  • 167
  • 263

2 Answers2

5

I thought panic! stops everything in Rust.

Not quite: panic! only stops¹ the current thread, which for single threaded programs stops the whole program. If you spawn another thread, the parent thread can detect whether or not the child thread panicked on joining.

Iron uses many threads to handle multiple requests in parallel. Apparently it just ignores panics in child threads...


¹ As DK. and Vladimir Matveev mentioned in the comments, it's not that simple. Multiple things can happen when a panic is "thrown". By default, the application starts unwinding (climbing down the stack) until "the end" of the stack or a catch_unwind is reached. In the former case, the thread is killed; in the latter it's up to the user to decide what happens. It's also possible to configure your build such that abort is called on panic!.

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
Lukas Kalbertodt
  • 79,749
  • 26
  • 255
  • 305
  • `panic!` doesn't necessarily *stop* the current thread. By default, it begins unwinding which will continue it *either* terminates the thread *or* it unwinds into a `catch_unwind` call. Alternately, it could just abort the whole process. – DK. Jul 15 '16 at 08:38
  • Note that it is possible to enable abort on panic in the latest Rust versions. – Vladimir Matveev Jul 15 '16 at 09:21
2

panic! in Rust is akin to exceptions in other languages, with two major differences:

  • you cannot specify a "type"
  • you cannot specify "data"

This makes it awkward to use it for out-of-bands signalling, and therefore reserves its use to "Oops" situations.

Otherwise, it behaves much in the same way in general: the current thread of execution unwinds (calling destructors as appropriate) until one of 3 things happen:

  • a destructor panic!: the process aborts immediately
  • the bottom of the stack is reached: the process aborts immediately
  • a catch_unwind is reached: the handler decides what to do

Along the way, the various destructors might poison some multi-thread data structures, which may cause other threads to panic when they attempt to use them, etc... that is however a library decision and is not enforced by the language itself.

Note: as noted by others, there is now another behavior for panics, immediate abortion. It shaves off some code, and obviously prevents graceful recovery.

Matthieu M.
  • 287,565
  • 48
  • 449
  • 722