errfmt

package
v0.4.1 Latest Latest
Warning

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

Go to latest
Published: Mar 28, 2026 License: EUPL-1.2 Imports: 10 Imported by: 0

Documentation

Overview

Package errors provides infrastructure adapters for error formatting.

This package implements the ErrorFormatter port from the domain layer, providing concrete formatters for different output modes:

  • JSONErrorFormatter: Machine-readable JSON output for CI/CD pipelines
  • HumanErrorFormatter: Human-readable CLI output with color and formatting

Architecture:

  • Domain defines: ErrorFormatter port interface, StructuredError type
  • Infrastructure provides: JSONErrorFormatter, HumanErrorFormatter adapters
  • Application/CLI inject: Formatter via dependency injection

Example usage:

// JSON output for programmatic consumption
formatter := errors.NewJSONErrorFormatter()
output := formatter.FormatError(structuredErr)
// {"error_code":"USER.INPUT.MISSING_FILE","message":"workflow file not found",...}

// Human-readable output for CLI
formatter := errors.NewHumanErrorFormatter()
output := formatter.FormatError(structuredErr)
// [USER.INPUT.MISSING_FILE] workflow file not found

Component: C047 Structured Error Codes Taxonomy Layer: Infrastructure

Package errfmt provides infrastructure implementations for error formatting and hint generation. This package implements the error formatting ports defined in the domain layer.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func CommandFailureHintGenerator

func CommandFailureHintGenerator(err *errors.StructuredError) []errors.Hint

CommandFailureHintGenerator examines command execution errors and generates actionable hints such as permission checks and command availability verification.

Detection:

  • Matches errors with code EXECUTION.COMMAND.FAILED
  • Extracts exit code from error Details["exit_code"]
  • Extracts command from error Details["command"]

Hints generated:

  • Permission checks for exit code 126
  • Command not found suggestions for exit code 127
  • Generic troubleshooting for other exit codes

Implementation notes:

  • Uses exit code to determine specific failure mode
  • Returns empty slice if no command context available
  • Thread-safe: no shared mutable state

func FileNotFoundHintGenerator

func FileNotFoundHintGenerator(err *errors.StructuredError) []errors.Hint

FileNotFoundHintGenerator examines file-not-found errors and generates actionable hints such as "did you mean?" suggestions for similar files and commands to list available files.

Detection:

  • Matches errors with code USER.INPUT.MISSING_FILE
  • Extracts file path from error Details["path"]

Hints generated:

  • Similar filename suggestions (using Levenshtein distance)
  • Command to list available files (e.g., "Run 'awf list' to see workflows")
  • Working directory verification prompt

Implementation notes:

  • Uses os.ReadDir to scan directory for similar files
  • Returns empty slice if directory read fails (graceful degradation)
  • Limits suggestions to 3 closest matches to avoid overwhelming user
  • Thread-safe: no shared mutable state

func InvalidStateHintGenerator

func InvalidStateHintGenerator(err *errors.StructuredError) []errors.Hint

InvalidStateHintGenerator examines invalid state reference errors and generates actionable hints such as "did you mean?" suggestions for similar state names.

Detection:

  • Matches errors with code WORKFLOW.VALIDATION.MISSING_STATE
  • Extracts referenced state name from error Details["state"]
  • Extracts available states from error Details["available_states"]

Hints generated:

  • Similar state name suggestions (using Levenshtein distance)
  • List of all available states if no close match found

Implementation notes:

  • Uses Levenshtein distance to find closest matching state names
  • Returns empty slice if no state context available
  • Limits suggestions to 3 closest matches to avoid overwhelming user
  • Thread-safe: no shared mutable state

func MissingInputHintGenerator

func MissingInputHintGenerator(err *errors.StructuredError) []errors.Hint

MissingInputHintGenerator examines missing input variable errors and generates actionable hints such as listing required inputs and providing example values.

Detection:

  • Matches errors with code USER.INPUT.VALIDATION_FAILED
  • Extracts missing input variable name from error Details["input"]
  • Extracts required inputs list from error Details["required_inputs"]

Hints generated:

  • Message indicating which input is missing
  • List of all required inputs with example values
  • Command example showing how to provide inputs

Implementation notes:

  • Extracts input name and required inputs from error details
  • Returns generic hint if no input context available
  • Thread-safe: no shared mutable state

func PluginDisabledHintGenerator

func PluginDisabledHintGenerator(err *errors.StructuredError) []errors.Hint

PluginDisabledHintGenerator examines disabled plugin errors and generates actionable hints to re-enable the plugin.

Detection:

  • Matches errors with code EXECUTION.PLUGIN.DISABLED
  • Extracts plugin name from error Details["plugin"]

Hints generated:

  • Command to re-enable the plugin
  • Command to list all plugins and their status

func YAMLSyntaxHintGenerator

func YAMLSyntaxHintGenerator(err *errors.StructuredError) []errors.Hint

YAMLSyntaxHintGenerator examines YAML parsing errors and generates actionable hints such as line/column pointers and expected format guidance.

Detection:

  • Matches errors with code WORKFLOW.PARSE.YAML_SYNTAX
  • Extracts line/column information from error Details

Hints generated:

  • Line and column position of syntax error
  • Expected YAML format guidance
  • Common YAML syntax mistake suggestions

Implementation notes:

  • Extracts line/column from error details if available
  • Returns generic YAML syntax guidance if no position info
  • Thread-safe: no shared mutable state

Types

type HumanErrorFormatter

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

HumanErrorFormatter implements the ErrorFormatter port interface, providing human-readable CLI output for structured errors with color and formatting.

Output format:

[USER.INPUT.MISSING_FILE] workflow file not found
  Details:
    path: /workflow.yaml
  Hint: Did you mean 'my-workflow.yaml'?

Usage:

formatter := NewHumanErrorFormatter(true, false, generators...)
output := formatter.FormatError(structuredErr)
fmt.Println(output)

Component: C047 Structured Error Codes Taxonomy (extended by C048) Layer: Infrastructure

func NewHumanErrorFormatter

func NewHumanErrorFormatter(colorEnabled, noHints bool, generators ...domainerrors.HintGenerator) *HumanErrorFormatter

NewHumanErrorFormatter creates a new HumanErrorFormatter instance.

Parameters:

  • colorEnabled: Whether to enable colored output
  • noHints: Whether to suppress hint generation
  • generators: Optional hint generators (if nil or empty, no hints generated)

Returns:

  • A new HumanErrorFormatter ready to format structured errors with optional hints

Example:

formatter := NewHumanErrorFormatter(true, false, FileNotFoundHintGenerator)
output := formatter.FormatError(err)

func (*HumanErrorFormatter) FormatError

FormatError converts a StructuredError into human-readable string representation.

Implements the ErrorFormatter port interface. Returns a formatted string with:

  • Error code prefix in brackets (e.g., "[USER.INPUT.MISSING_FILE]")
  • Human-readable message
  • Details section with key-value pairs (if present)
  • Color coding (if enabled): red for error code, normal for message

Parameters:

  • err: The structured error to format

Returns:

  • Human-readable string representation of the error

Example:

formatter := NewHumanErrorFormatter(true)
err := domainerrors.NewStructuredError(
    domainerrors.ErrorCodeUserInputMissingFile,
    "workflow file not found",
    map[string]any{"path": "/workflow.yaml"},
    nil,
)
output := formatter.FormatError(err)
// [USER.INPUT.MISSING_FILE] workflow file not found
//   Details:
//     path: /workflow.yaml

type JSONErrorFormatter

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

JSONErrorFormatter implements the ErrorFormatter port interface, providing machine-readable JSON output for structured errors.

Output format:

{
  "error_code": "USER.INPUT.MISSING_FILE",
  "message": "workflow file not found",
  "details": {"path": "/workflow.yaml"},
  "timestamp": "2025-01-15T10:30:45Z",
  "hints": ["Did you mean 'my-workflow.yaml'?"]
}

Usage:

formatter := NewJSONErrorFormatter(false, generators...)
output := formatter.FormatError(structuredErr)
fmt.Println(output)

Component: C047 Structured Error Codes Taxonomy, C048 Actionable Error Hints Layer: Infrastructure

func NewJSONErrorFormatter

func NewJSONErrorFormatter(noHints bool, generators ...domainerrors.HintGenerator) *JSONErrorFormatter

NewJSONErrorFormatter creates a new JSONErrorFormatter instance.

Parameters:

  • noHints: If true, suppresses hint generation (for scripted usage)
  • generators: Optional hint generators to invoke for contextual suggestions

Returns:

  • A new JSONErrorFormatter ready to format structured errors as JSON

Example:

formatter := NewJSONErrorFormatter(false, FileNotFoundHintGenerator, YAMLSyntaxHintGenerator)
output := formatter.FormatError(err)

func (*JSONErrorFormatter) FormatError

FormatError converts a StructuredError into JSON string representation.

Implements the ErrorFormatter port interface. Returns a JSON object containing:

  • error_code: hierarchical error code (e.g., "USER.INPUT.MISSING_FILE")
  • message: human-readable error message
  • details: structured key-value pairs for additional context
  • timestamp: ISO 8601 formatted timestamp
  • hints: array of actionable suggestions (if noHints is false)

Parameters:

  • err: The structured error to format

Returns:

  • JSON string representation of the error

Example:

formatter := NewJSONErrorFormatter(false, FileNotFoundHintGenerator)
err := domainerrors.NewStructuredError(
    domainerrors.ErrorCodeUserInputMissingFile,
    "workflow file not found",
    map[string]any{"path": "/workflow.yaml"},
    nil,
)
output := formatter.FormatError(err)
// {"error_code":"USER.INPUT.MISSING_FILE","message":"workflow file not found",...,"hints":[...]}

Jump to

Keyboard shortcuts

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