diagnostics

package module
v0.0.0-...-4f8cc29 Latest Latest
Warning

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

Go to latest
Published: Aug 30, 2026 License: GPL-3.0 Imports: 3 Imported by: 0

Documentation

Overview

Package diagnostics is the shared diagnostic-code framework: the reusable machinery a codebase uses to declare its OWN stable, documented diagnostic codes and render them as errors that point at a lookup page. It is deliberately code-namespace-AGNOSTIC. It owns the MECHANISM - the Code/Error types, the "[code] msg / see: url" rendering, the errors.Is matching, and the run-time sink plumbing - but never a catalog of codes. Each consumer instantiates a Domain with its own docs-URL layout and declares its own Code constants; the namespaces are entirely separate, so no code is ever shared across consumers. magus instantiates it for its MGS#### codes; gopherbuzz instantiates it separately for its BZZ#### codes.

It is its own module (github.com/egladman/magus/libs/diagnostics, at libs/diagnostics) precisely so both magus and gopherbuzz - which are separate Go modules - can each depend on it without depending on each other.

Index

Constants

This section is empty.

Variables

View Source
var ErrSentinel = errors.New("diag")

ErrSentinel matches any *Error via errors.Is, so a caller can test "is this a diagnostic error at all" without naming a specific code.

Functions

func Emit

func Emit(ctx context.Context, ev Event)

Emit records ev to the sink in ctx, or is a no-op when none is installed (the common CLI path).

func WithSink

func WithSink(ctx context.Context, s Sink) context.Context

WithSink returns ctx carrying s, so a deep emission site can reach the sink without threading it through every signature.

Types

type Code

type Code string

Code is a stable diagnostic identifier, e.g. "MGS1001" or "BZZ0003". Its prefix and numbering are a convention of the consumer that declares it; this package never interprets the string.

func (Code) Error

func (c Code) Error() string

Error lets a Code serve as an errors.Is sentinel, so `errors.Is(err, MGS2007)` matches an *Error carrying that code - the idiomatic Go form (cf. syscall.Errno). The rendered text is the bare code; a Code is an IDENTIFIER, not a message, so build an error that carries context with Domain.Errorf rather than returning a bare Code.

type Domain

type Domain struct {
	// contains filtered or unexported fields
}

Domain is one consumer's diagnostic namespace: how to build the docs URL for a Code in its family, and the factory for that consumer's coded errors. "Domain" here is the NSError sense - a namespace of related codes - not a network domain. A consumer creates one (magus for MGS, gopherbuzz for BZZ) and declares its own Code constants alongside it.

func New

func New(urlFn func(Code) string) *Domain

New returns a Domain whose docs URL for a Code is built by urlFn.

func (*Domain) Errorf

func (d *Domain) Errorf(c Code, format string, args ...any) *Error

Errorf builds an *Error with c, a formatted message, and c's docs URL captured for rendering.

func (*Domain) Format

func (d *Domain) Format(c Code, msg string) string

Format renders a code+message as a single slog-friendly line: "[CODE] msg (see URL)".

func (*Domain) URL

func (d *Domain) URL(c Code) string

URL returns the docs page for c under this domain.

func (*Domain) Wrapf

func (d *Domain) Wrapf(c Code, cause error, format string, args ...any) *Error

Wrapf builds a coded *Error over an existing cause: it renders "[code] msg / see: url" (cause is NOT spliced into the message) and Unwraps to cause, so errors.Is(err, cause) still matches. Use it when a sentinel error must keep matching while the error also gains a lookupable code - e.g. adding a code to an error whose sentinel already drives control flow.

type Error

type Error struct {
	Code Code
	Msg  string
	// contains filtered or unexported fields
}

Error is a coded diagnostic error: a Code, a human message, and - when built through a Domain - the docs URL to render. A bare literal &Error{Code: X} carries no URL and is meant only as an errors.Is target.

func (*Error) BuzzError

func (e *Error) BuzzError() map[string]string

BuzzError exposes this diagnostic to a Buzz `catch` as structured fields, satisfying gopherbuzz's vm.StructuredError.

Without it a caught error is just its rendered sentence, so a magusfile deciding what to do about a failure has to substring-match prose that exists for humans and is free to be reworded. The code is the stable identifier - it is already the thing docs, the knowledge graph and `magus explain` key off - so it is what a caller should branch on:

catch (e) { if (e.code == "MGS2001") { ... } }

url is included when the domain captured one, so a magusfile can surface the same link the CLI prints rather than reconstructing it.

func (*Error) Error

func (e *Error) Error() string

Error renders "[CODE] message" plus a "see: <url>" line when a docs URL was captured.

func (*Error) Is

func (e *Error) Is(target error) bool

Is matches ErrSentinel (any diagnostic error), a bare Code sentinel with the same code, or another *Error carrying the same code. The Code case is the idiomatic target: errors.Is(err, MGS2007).

func (*Error) Unwrap

func (e *Error) Unwrap() error

Unwrap returns the wrapped cause (nil if none), so errors.Is/As can reach an underlying sentinel or error a coded error was layered over. See Domain.Wrapf.

type Event

type Event struct {
	Code    Code   `json:"code"              yaml:"code"`
	Message string `json:"message,omitempty" yaml:"message,omitempty"`
	Unit    string `json:"unit,omitempty"    yaml:"unit,omitempty"`
}

Event is one diagnostic fired during a run: the code, a message, and the unit that emitted it ("<project>:<target>", a project path, or empty).

type Sink

type Sink interface {
	Record(Event)
}

Sink records diagnostics fired during a run; it must be safe for concurrent use. A run installs one in its context so a deep emission site reaches it via Emit; consumers drain it.

Jump to

Keyboard shortcuts

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