ifc_lite_server/panic_strategy.rs
1// This Source Code Form is subject to the terms of the Mozilla Public
2// License, v. 2.0. If a copy of the MPL was not distributed with this
3// file, You can obtain one at https://mozilla.org/MPL/2.0/.
4
5//! Self-check for the panic strategy this binary was actually built with.
6//!
7//! `CatchPanicLayer` (see `build_router`) only contains a malformed-IFC panic
8//! to the offending request if the build unwinds. Under
9//! `[profile.release] panic = 'abort'` the panic is a process abort: the layer
10//! never runs, `spawn_blocking` never turns it into a `JoinError`, and every
11//! other tenant's in-flight request dies with the process. That precondition
12//! is a property of the ARTEFACT, so the release pipeline asserts it against
13//! the artefact (`--panic-strategy-selftest`, wired in
14//! `.github/workflows/server-binaries.yml`) rather than against the flags that
15//! were meant to produce it.
16
17/// Argument that runs the self-check instead of starting the server.
18pub const SELFTEST_FLAG: &str = "--panic-strategy-selftest";
19
20/// Line printed by the self-check when the binary unwinds.
21pub const UNWIND_VERDICT: &str = "panic-strategy: unwind";
22
23/// Whether a panic in this binary unwinds (`true`) rather than aborting.
24///
25/// There is no `false` in a built binary: under `panic = "abort"` the panic
26/// below kills the process with `SIGABRT` and this never returns. That is what
27/// makes it a usable CI assertion: the two observable outcomes are
28/// [`UNWIND_VERDICT`] on stdout and a dead process. The `false` arm exists so
29/// the function is total. The deliberate panic's message reaches stderr,
30/// named as the self-check so it cannot be read as a crash; that is the whole
31/// cost of not touching the process-global panic hook here.
32///
33/// Not unit-tested: `cargo test` builds with the `test` profile, which
34/// unwinds, so an in-process assertion could only ever say "true" and the
35/// abort direction takes the harness with it. The "Assert the built binary
36/// unwinds" step in `.github/workflows/server-binaries.yml` is the test.
37pub fn panic_unwinds() -> bool {
38 std::panic::catch_unwind(|| {
39 panic!("{SELFTEST_FLAG}: deliberate panic, this is the self-check, not a crash");
40 })
41 .is_err()
42}