runtimex

package module
v0.0.0-...-ec3a7b5 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 30, 2026 License: GPL-3.0 Imports: 2 Imported by: 21

README

Golang Runtime Extensions

GoDoc Build Status codecov

The runtimex Go package contains helpers for code paths:

  1. that are not expected to fail;

  2. where failure indicates a programmer error or an unrecoverable condition.

For example:

import "github.com/bassosimone/runtimex"

// 1. Runtime assertions invoking `panic` when invariants are not met.
runtimex.Assert(txp != nil)

// 2. Quick error unwrapping for functions that can't fail.
data := runtimex.PanicOnError1(json.Marshal("always marshals"))

// Avoiding `if err != nil { panic(err) }` in packages only used for testing.
req := runtimex.PanicOnError1(http.NewRequest("GET", URL, nil))

// Avoiding `if err != nil { log.Fatal(err) }` in `main` code.
resp := runtimex.LogFatalOnError1(txp.RoundTrip(req))

Installation

To add this package as a dependency to your module:

go get github.com/bassosimone/runtimex

Development

To run the tests:

go test -v .

To measure test coverage:

go test -v -cover .

License

SPDX-License-Identifier: GPL-3.0-or-later

History

Adapted from ooni/probe-cli/internal/runtimex and inspired by m-lab/go/rtx.

Documentation

Overview

Package runtimex contains helpers for code paths that are not expected to fail and where failure indicates a programmer error or an unrecoverable condition.

When to use what

Assert: For enforcing invariants in library code. Document the invariant and its justification in a comment above the assertion. Use these for conditions that should be impossible if the program is correct.

PanicOnErrorN: For unwrapping `(value, ..., error)` returns where the error cannot occur in correct usage but ignoring the error feels sloppy.

LogFatalOnErrorN: In main() functions when you want to log and exit.

History

This package was originally inspired by github.com/m-lab/go/rtx.

Index

Constants

This section is empty.

Variables

View Source
var LogFatalFunc = log.Fatal

LogFatalFunc is the function that LogFatalOnError0, LogFatalOnError1, LogFatalOnError2, and LogFatalOnError3 invoke when they receive a non-nil error. The default is log.Fatal, which logs and calls `os.Exit(1)`, bypassing every pending defer.

Replace from `main` before starting goroutines to change the failure behavior — for example, to call `deferexit.Panic(1)` after logging so that deferred cleanup actually runs. Not safe to mutate concurrently.

Functions

func Assert

func Assert(value bool)

Assert panics if the given value is false. The value passed to `panic()` is an error constructed using errors.New.

You typically use this function to assert runtime invariants in your codebase to make it more robust. Document the invariant and its justification in a comment above the assertion. For example:

// Invariant: msg is never nil after successful initialization. This is
// guaranteed by the constructor, which validates input.
runtimex.Assert(cfg.msg != nil)

The correct approach is to assert for conditions that should be impossible if the program is correct.

func LogFatalOnError0

func LogFatalOnError0(err error)

LogFatalOnError0 exits with a fatal error if err is not nil.

It is equivalent to:

if err != nil {
	log.Fatal(err)
}

func LogFatalOnError1

func LogFatalOnError1[T1 any](v1 T1, err error) T1

LogFatalOnError1 exits with a fatal error if err is not nil. Otherwise, it returns the given value `v1`.

It is equivalent to:

v1, err := fx()
if err != nil {
	log.Fatal(err)
}

func LogFatalOnError2

func LogFatalOnError2[T1, T2 any](v1 T1, v2 T2, err error) (T1, T2)

LogFatalOnError2 exits with a fatal error if err is not nil. Otherwise, it returns the given values `v1` and `v2`.

It is equivalent to:

v1, v2, err := fx()
if err != nil {
	log.Fatal(err)
}

func LogFatalOnError3

func LogFatalOnError3[T1, T2, T3 any](v1 T1, v2 T2, v3 T3, err error) (T1, T2, T3)

LogFatalOnError3 exits with a fatal error if err is not nil. Otherwise, it returns the given values `v1`, `v2`, and `v3`.

It is equivalent to:

v1, v2, v3, err := fx()
if err != nil {
	log.Fatal(err)
}

func PanicOnError0

func PanicOnError0(err error)

PanicOnError0 panics if the given err is not nil. The value passed to `panic()` is the given err value.

You typically use this function to assert runtime invariants in your codebase to make it more robust. For example:

runtimex.PanicOnError0(operationThatCannotFail())

The correct approach is to assert for errors that cannot possibly happen (e.g., [json.Marshal] applied to a struct that can always be marshalled to a JSON string).

func PanicOnError1

func PanicOnError1[T1 any](v1 T1, err error) T1

PanicOnError1 panics if the given err is not nil. The value passed to `panic()` is the given err value. Otherwise, it returns the given value `v1`.

This code is equivalent to:

v1, err := fx()
if err != nil {
	panic(err)
}

but is more compact and improves readability when chaining operations.

func PanicOnError2

func PanicOnError2[T1, T2 any](v1 T1, v2 T2, err error) (T1, T2)

PanicOnError2 panics if the given err is not nil. The value passed to `panic()` is the given err value. Otherwise, it returns the given values `v1` and `v2`.

This code is equivalent to:

v1, v2, err := fx()
if err != nil {
	panic(err)
}

but is more compact and improves readability when chaining operations.

func PanicOnError3

func PanicOnError3[T1, T2, T3 any](v1 T1, v2 T2, v3 T3, err error) (T1, T2, T3)

PanicOnError3 panics if the given err is not nil. The value passed to `panic()` is the given err value. Otherwise, it returns the given values `v1`, v2, and `v3`.

This code is equivalent to:

v1, v2, v3, err := fx()
if err != nil {
	panic(err)
}

but is more compact and improves readability when chaining operations.

Types

This section is empty.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL