must

package module
v2.0.0 Latest Latest
Warning

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

Go to latest
Published: Jan 18, 2022 License: Apache-2.0 Imports: 0 Imported by: 22

README

Go library to shorten handling of impossible conditions

Go Reference

must.OK(os.Unsetenv("FOO"))
bs := must.OK1(json.Marshal(dataStructureDefinedInCode))
defer must.Do(f.Close)

is

if err := os.Unsetenv("FOO"); err != nil {
     panic(err)
}
bs, err := json.Marshal(dataStructureDefinedInCode)
if err != nil {
    panic(err)
}
defer func() {
    if err := f.Close(); err != nil {
        panic(err)
    }
}()

Why panic?

Go error handling style is practical for majority of errors. However not all errors are meaningful and actionable by the caller, so it does not make sense to surface them.

Go tacitly acknowledges it by providing functions regex.MustCompile and template.Must in the standard library. This library expands on the same idea.

Where is it useful?

The library is proven to be useful in the following situations:

  • Programming errors in all kinds of code, similar to regex.MustCompile,
  • Filesystem-related errors in a build system,
  • Fatal errors in server-side SaaS code.

The last point needs an explanation.

Unlike CLI tools where errors ought to be handled in a way meaningful to a user who might not know the internals of the application, server-side SaaS applications are run by the SREs or developers who do not need the extra wrapping, and instead require fatal errors to be delivered reliably and with all gory details.

Passing errors up the stack in a regular Go way risks losing the error (by forgetting to wrap it, or by swallowing it completely), and prevents the original stacktrace from being surfaced. panicing at the place of fatal error is reliable and precise.

Is it a good idea to use must everywhere?

Definitely not. Go rules for error handling are well thought-out. Reserve must for programming errors and impossible conditions.

Copyright Tectonic Networks, Inc.

Licensed under Apache 2.0 license.

Authors:

Documentation

Overview

Package must is a library to shorten handling of impossible conditions

must.OK(os.Unsetenv("FOO"))
bytes := must.OK1(json.Marshal(dataStructureDefinedInCode))
defer must.Do(f.Close)

is

if err := os.Unsetenv("FOO"); err != nil {
    panic(err)
}

bytes, err := json.Marshal(dataStructureDefinedInCode)
if err != nil {
    panic(err)
}

defer func() {
    if err := f.Close(); err != nil{
        panic(err)
    }
}()

Go error handling style is practical for majority of errors. However not all errors are meaningful and actionable by the caller, so it does not make sense to surface them.

Go tacitly acknowledges it by providing functions regex.MustCompile and template.Must in the standard library. This library expands on the same idea.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Do

func Do(fn func() error)

Do calls the function and panics on error.

For use primarily in defer statements.

BAD example:

// f.Close will be called now, must.OK will be called on function exit
defer must.OK(f.Close())

GOOD example:

defer must.Do(f.Close)

func OK

func OK(err error)

OK panics on error

func OK1

func OK1[T any](t T, err error) T

OK1 panics on error, returns the first argument otherwise

func OK2

func OK2[T1, T2 any](t1 T1, t2 T2, err error) (T1, T2)

OK2 panics on error, returns the first arguments otherwise

func OK3

func OK3[T1, T2, T3 any](t1 T1, t2 T2, t3 T3, err error) (T1, T2, T3)

OK3 panics on error, returns the first arguments otherwise

func OK4

func OK4[T1, T2, T3, T4 any](t1 T1, t2 T2, t3 T3, t4 T4, err error) (T1, T2, T3, T4)

OK4 panics on error, returns the first arguments otherwise

Types

This section is empty.

Jump to

Keyboard shortcuts

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