CI Go Reference Go Report Card
A drop-in replacement for oklog/run with automatic panic recovery.
- Drop-in replacement: Compatible with
oklog/run.GroupAPI - Automatic panic recovery: All panics in actors are caught and converted to errors
- Custom panic handlers: Optional custom handling of panic situations
- Zero dependencies: Only depends on
oklog/run - 100% test coverage: Thoroughly tested with comprehensive test suite
go get github.com/dio/run
package main import ( "errors" "fmt" "log" "github.com/dio/run" ) func main() { g := run.New() // Add an actor that might panic g.Add(func() error { // This panic will be caught and converted to an error panic("something went wrong") }, func(err error) { log.Printf("Actor interrupted: %v", err) }) // Add a normal actor g.Add(func() error { return errors.New("normal error") }, func(err error) { log.Printf("Actor interrupted: %v", err) }) if err := g.Run(); err != nil { log.Printf("Group failed: %v", err) } }
The run.Group works exactly like oklog/run.Group but with automatic panic recovery:
g := run.New() g.Add(execute, interrupt) err := g.Run()
You can provide a custom panic handler to process panics in your own way:
g := run.NewWithHandler(func(panicValue any, stackTrace string) error { // Log the panic with custom formatting log.Printf("PANIC: %v\nStack trace:\n%s", panicValue, stackTrace) // Return a custom error return fmt.Errorf("actor panicked: %v", panicValue) })
When an actor panics, it's automatically converted to a PanicError:
err := g.Run() if err != nil { if panicErr, ok := err.(*run.PanicError); ok { fmt.Printf("Actor panicked with value: %v\n", panicErr.Value) fmt.Printf("Stack trace:\n%s\n", panicErr.StackTrace) } }
type Group struct { // PanicHandler is called when an actor panics. // If nil, panics are converted to PanicError and returned. PanicHandler func(panicValue any, stackTrace string) error }
type PanicError struct { Value any // The panic value StackTrace string // Stack trace at panic time }
func New() *Group
Creates a new Group with panic recovery enabled.
func NewWithHandler(handler func(panicValue any, stackTrace string) error) *Group
Creates a new Group with a custom panic handler.
func (g *Group) Add(execute func() error, interrupt func(error))
Add an actor to the group. This is a drop-in replacement for oklog/run.Group.Add().
func (g *Group) Run() error
Execute all actors. This is identical to oklog/run.Group.Run().
- Go 1.24+
- golangci-lint (installed via
go tool)
go build ./...
go test -v -race -coverprofile=coverage.out ./...
go tool cover -html=coverage.outgo tool golangci-lint run
go tool golangci-lint fmt
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Make your changes
- Add tests for your changes
- Ensure all tests pass (
go test ./...) - Run linting (
go tool golangci-lint run) - Commit your changes (
git commit -am 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
This project is licensed under the MIT License - see the LICENSE file for details.
- oklog/run - The original actor model implementation
- Inspired by the need for safer concurrent programming in Go