Documentation
¶
Overview ¶
Package safe provides panic-recovery wrappers for extension entry points. The host uses these to prevent a misbehaving extension from taking down unrelated cells in a multi-cell deployment.
Every exported helper logs the panic with the extension name, a short message, and the stack trace, then converts the panic into a typed error. Callers decide whether to keep running (Poll, host functions) or mark the cell as failed-to-start (Setup) or swallow (Teardown, Finalize — we're already shutting down).
Index ¶
- func CallFinalize(cap ext.Capability, id uint64, logger *slog.Logger)
- func CallPoll(cap ext.Capability, logger *slog.Logger) (ev ext.StepEvent, ok bool)
- func CallSetup(cap ext.Capability, env ext.SetupEnv, logger *slog.Logger) (err error)
- func CallTeardown(ctx context.Context, cap ext.Capability, logger *slog.Logger)
- func HostFunc[F any](name, fname string, fn F, logger *slog.Logger) F
- func RecoverHost(name, fname string, logger *slog.Logger)
- type ErrExtensionPanic
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func CallFinalize ¶
func CallFinalize(cap ext.Capability, id uint64, logger *slog.Logger)
CallFinalize invokes cap.Finalize(id) under panic recovery. Logs and swallows panics — the step has already run, we're cleaning up.
func CallPoll ¶
CallPoll invokes cap.Poll() under panic recovery. On panic, logs and returns (zero-value, false) so the step loop treats it as "no event available" and continues. A repeatedly-panicking extension will log on every tick — callers may want to rate-limit logging upstream.
func CallSetup ¶
CallSetup invokes cap.Setup(env) under panic recovery. Returns any error the extension returned OR an *ErrExtensionPanic if Setup panicked.
func CallTeardown ¶
CallTeardown invokes cap.Teardown(ctx) under panic recovery. Logs and swallows panics — teardown happens during shutdown, where propagating an error accomplishes nothing.
func HostFunc ¶
HostFunc wraps a host-function body in panic recovery. Returns a function with the same signature. Use when registering host imports with wazero:
builder.NewFunctionBuilder().WithFunc(
safe.HostFunc("my_extension", "my_func", myFuncBody, logger),
).Export("my_func")
The wrapped function returns the same values the original would, or zero values on panic. Callers that need a specific error-code convention should branch on a sentinel rather than relying on zero values.
The name arg is the extension identity for logging; fname is the host function name (e.g., "udp_listen"). Both appear in the log record.
func RecoverHost ¶
RecoverHost is the raw building block. Call from inside a host function body:
func myHostFunc(ctx context.Context, mod api.Module, reqPtr, reqLen uint32) uint32 {
defer safe.RecoverHost("ext-udp", "udp_listen", logger)
// ...actual work...
}
Unlike the Call* helpers, this does not convert the panic to a return value — the caller decides what to return. Used for side-effect-only host functions or where the error code convention already exists.
Types ¶
type ErrExtensionPanic ¶
type ErrExtensionPanic struct {
Extension string
Phase string // "setup", "teardown", "poll", "finalize", "host"
Value any // the recovered panic value
}
ErrExtensionPanic is returned wrapped when a recovered panic is converted to an error. Callers use errors.Is to distinguish it from genuine extension errors.
func (*ErrExtensionPanic) Error ¶
func (e *ErrExtensionPanic) Error() string