Documentation ¶
Overview ¶
The panicwrap package provides functions for capturing and handling panics in your application. It does this by re-executing the running application and monitoring stderr for any panics. At the same time, stdout/stderr/etc. are set to the same values so that data is shuttled through properly, making the existence of panicwrap mostly transparent.
Panics are only detected when the subprocess exits with a non-zero exit status, since this is the only time panics are real. Otherwise, "panic-like" output is ignored.
Index ¶
Constants ¶
const ( DEFAULT_COOKIE_KEY = "cccf35992f8f3cd8d1d28f0109dd953e26664531" DEFAULT_COOKIE_VAL = "7c28215aca87789f95b406b8dd91aa5198406750" )
Variables ¶
This section is empty.
Functions ¶
func BasicMonitor ¶
func BasicMonitor(f HandlerFunc) error
BasicMonitor calls Wrap with Monitor set to true on supported platforms. It forks your program and runs it again form the start. In one process BasicMonitor never returns, it just listens on stderr of the other process, and calls your handler when a panic is seen. In the other it either returns nil to indicate that the panic monitoring is enabled, or an error to indicate that something else went wrong.
func BasicWrap ¶
func BasicWrap(f HandlerFunc) (int, error)
BasicWrap calls Wrap with the given handler function, using defaults for everything else. See Wrap and WrapConfig for more information on functionality and return values.
func Wrap ¶
func Wrap(c *WrapConfig) (int, error)
Wrap wraps the current executable in a handler to catch panics. It returns an error if there was an error during the wrapping process. If the error is nil, then the int result indicates the exit status of the child process. If the exit status is -1, then this is the child process, and execution should continue as normal. Otherwise, this is the parent process and the child successfully ran already, and you should exit the process with the returned exit status.
This function should be called very very early in your program's execution. Ideally, this runs as the first line of code of main.
Once this is called, the given WrapConfig shouldn't be modified or used any further.
func Wrapped ¶
func Wrapped(c *WrapConfig) bool
Wrapped checks if we're already wrapped according to the configuration given.
Wrapped is very cheap and can be used early to short-circuit some pre-wrap logic your application may have.
Types ¶
type HandlerFunc ¶
type HandlerFunc func(string)
HandlerFunc is the type called when a panic is detected.
type WrapConfig ¶
type WrapConfig struct { // Handler is the function called when a panic occurs. Handler HandlerFunc // The cookie key and value are used within environmental variables // to tell the child process that it is already executing so that // wrap doesn't re-wrap itself. CookieKey string CookieValue string // If true, the panic will not be mirrored to the configured writer // and will instead ONLY go to the handler. This lets you effectively // hide panics from the end user. This is not recommended because if // your handler fails, the panic is effectively lost. HidePanic bool // If true, panicwrap will boot a monitor sub-process and let the parent // run the app. This mode is useful for processes run under supervisors // like runit as signals get sent to the correct codebase. This is not // supported when GOOS=windows, and ignores c.Stderr and c.Stdout. Monitor bool // The amount of time that a process must exit within after detecting // a panic header for panicwrap to assume it is a panic. Defaults to // 300 milliseconds. DetectDuration time.Duration // The writer to send the stderr to. If this is nil, then it defaults // to os.Stderr. Writer io.Writer // The writer to send stdout to. If this is nil, then it defaults to // os.Stdout. Stdout io.Writer }
WrapConfig is the configuration for panicwrap when wrapping an existing binary. To get started, in general, you only need the BasicWrap function that will set this up for you. However, for more customizability, WrapConfig and Wrap can be used.