Giter VIP home page Giter VIP logo

panicwrap's Introduction

panicwrap

panicwrap is a Go library that re-executes a Go binary and monitors stderr output from the binary for a panic. When it find a panic, it executes a user-defined handler function. Stdout, stderr, stdin, signals, and exit codes continue to work as normal, making the existence of panicwrap mostly invisble to the end user until a panic actually occurs.

Since a panic is truly a bug in the program meant to crash the runtime, globally catching panics within Go applications is not supposed to be possible. Despite this, it is often useful to have a way to know when panics occur. panicwrap allows you to do something with these panics, such as writing them to a file, so that you can track when panics occur.

panicwrap is not a panic recovery system. Panics indicate serious problems with your application and should crash the runtime. panicwrap is just meant as a way to monitor for panics. If you still think this is the worst idea ever, read the section below on why.

This is a fork of mitchellh/panicwrap which adds support for monitoring for panics without interrupting signal handling on supported platforms. More information is available in the documentation.

Features

  • SIMPLE!
  • Works with all Go applications on all platforms Go supports
  • Custom behavior when a panic occurs
  • Stdout, stderr, stdin, exit codes, and signals continue to work as expected.

Usage

Using panicwrap is simple. It behaves a lot like fork, if you know how that works. A basic example is shown below.

Because it would be sad to panic while capturing a panic, it is recommended that the handler functions for panicwrap remain relatively simple and well tested. panicwrap itself contains many tests.

package main

import (
	"fmt"
	"github.com/mitchellh/panicwrap"
	"os"
)

func main() {
	exitStatus, err := panicwrap.BasicWrap(panicHandler)
	if err != nil {
		// Something went wrong setting up the panic wrapper. Unlikely,
		// but possible.
		panic(err)
	}

	// If exitStatus >= 0, then we're the parent process and the panicwrap
	// re-executed ourselves and completed. Just exit with the proper status.
	if exitStatus >= 0 {
		os.Exit(exitStatus)
	}

	// Otherwise, exitStatus < 0 means we're the child. Continue executing as
	// normal...

	// Let's say we panic
	panic("oh shucks")
}

func panicHandler(output string) {
	// output contains the full output (including stack traces) of the
	// panic. Put it in a file or something.
	fmt.Printf("The child panicked:\n\n%s\n", output)
	os.Exit(1)
}

How Does it Work?

panicwrap works by re-executing the running program (retaining arguments, environmental variables, etc.) and monitoring the stderr of the program. Since Go always outputs panics in a predictable way with a predictable exit code, panicwrap is able to reliably detect panics and allow the parent process to handle them.

WHY?! Panics should CRASH!

Yes, panics should crash. They are 100% always indicative of bugs. However, in some cases, such as user-facing programs (programs like Packer or Docker), it is up to the user to report such panics. This is unreliable, at best, and it would be better if the program could have a way to automatically report panics. panicwrap provides a way to do this.

For backend applications, it is easier to detect crashes (since the application exits). However, it is still nice sometimes to more intelligently log panics in some way. For example, at HashiCorp, we use panicwrap to log panics to timestamped files with some additional data (configuration settings at the time, environmental variables, etc.)

The goal of panicwrap is not to hide panics. It is instead to provide a clean mechanism for handling them before bubbling the up to the user and ultimately crashing.

panicwrap's People

Contributors

mitchellh avatar kattrali avatar conradirwin avatar emersion avatar bmeyers22 avatar dcondomitti avatar jmshal avatar aarch64 avatar eclipseo avatar toasterson avatar dre1080 avatar fractalwrench avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.