validation

package
v2.2.6 Latest Latest
Warning

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

Go to latest
Published: Jan 31, 2026 License: Apache-2.0 Imports: 14 Imported by: 0

Documentation

Overview

Package validation provides functional validation types and operations for the codec system.

This package implements a validation monad that accumulates errors during validation operations, making it ideal for form validation, data parsing, and other scenarios where you want to collect all validation errors rather than failing on the first error.

Core Concepts

Validation[A]: Represents the result of a validation operation as Either[Errors, A]:

  • Left(Errors): Validation failed with one or more errors
  • Right(A): Successfully validated value of type A

ValidationError: A detailed error type that includes:

  • Value: The actual value that failed validation
  • Context: The path through nested structures (e.g., "user.address.zipCode")
  • Message: Human-readable error description
  • Cause: Optional underlying error

Context: A stack of ContextEntry values that tracks the validation path through nested data structures, enabling precise error reporting.

Basic Usage

Creating validation results:

// Success case
valid := validation.Success(42)

// Failure case
invalid := validation.Failures[int](validation.Errors{
	&validation.ValidationError{
		Value:    "not a number",
		Message:  "expected integer",
		Context:  nil,
	},
})

Using with context:

failWithMsg := validation.FailureWithMessage[int]("invalid", "must be positive")
result := failWithMsg([]validation.ContextEntry{
	{Key: "age", Type: "int"},
})

Applicative Validation

The validation type supports applicative operations, allowing you to combine multiple validations and accumulate all errors:

type User struct {
	Name  string
	Email string
	Age   int
}

validateName := func(s string) validation.Validation[string] {
	if len(s) > 0 {
		return validation.Success(s)
	}
	return validation.Failures[string](/* error */)
}

// Combine validations - all errors will be collected
result := validation.Ap(validation.Ap(validation.Ap(
	validation.Of(func(name string) func(email string) func(age int) User {
		return func(email string) func(age int) User {
			return func(age int) User {
				return User{name, email, age}
			}
		}
	}),
)(validateName("")))(validateEmail("")))(validateAge(-1))

Error Formatting

ValidationError implements custom formatting for detailed error messages:

err := &ValidationError{
	Value:    "abc",
	Context:  []ContextEntry{{Key: "user"}, {Key: "age"}},
	Message:  "expected integer",
}

fmt.Printf("%v", err)   // at user.age: expected integer
fmt.Printf("%+v", err)  // at user.age: expected integer
                        //   value: "abc"

Monoid Operations

The package provides monoid instances for combining validations:

// Combine validation results
m := validation.ApplicativeMonoid(stringMonoid)
combined := m.Concat(validation.Success("hello"), validation.Success(" world"))
// Result: Success("hello world")

Integration

This package integrates with:

  • either: Validation is built on Either for error handling
  • array: For collecting multiple errors
  • monoid: For combining validation results
  • reader: For context-dependent validation operations

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Applicative

func Applicative[A, B any]() applicative.Applicative[A, B, Validation[A], Validation[B], Validation[func(A) B]]

Applicative creates an Applicative instance for Validation with error accumulation.

This returns a lawful Applicative that accumulates validation errors using the Errors monoid. Unlike the standard Either applicative which fails fast, this validation applicative collects all errors when combining independent validations with Ap.

The returned instance satisfies all applicative laws:

  • Identity: Ap(Of(identity))(v) == v
  • Homomorphism: Ap(Of(f))(Of(x)) == Of(f(x))
  • Interchange: Ap(Of(f))(u) == Ap(Map(f => f(y))(u))(Of(y))
  • Composition: Ap(Ap(Map(compose)(f))(g))(x) == Ap(f)(Ap(g)(x))

Key behaviors:

  • Of: lifts a value into a successful Validation (Right)
  • Map: transforms successful values, preserves failures (standard functor)
  • Ap: when both operands fail, combines all errors using the Errors monoid

This is particularly useful for form validation, configuration validation, and any scenario where you want to collect all validation errors at once rather than stopping at the first failure.

Example - Validating Multiple Fields:

app := Applicative[string, User]()

// Validate individual fields
validateName := func(name string) Validation[string] {
	if len(name) < 3 {
		return Failure("Name must be at least 3 characters")
	}
	return Success(name)
}

validateAge := func(age int) Validation[int] {
	if age < 18 {
		return Failure("Must be 18 or older")
	}
	return Success(age)
}

// Create a curried constructor
makeUser := func(name string) func(int) User {
	return func(age int) User {
		return User{Name: name, Age: age}
	}
}

// Combine validations - all errors are collected
name := validateName("ab")  // Failure: name too short
age := validateAge(16)      // Failure: age too low

result := app.Ap(age)(app.Ap(name)(app.Of(makeUser)))
// result contains both validation errors:
// - "Name must be at least 3 characters"
// - "Must be 18 or older"

Type Parameters:

  • A: The input value type (Right value)
  • B: The output value type after transformation

Returns:

An Applicative instance with Of, Map, and Ap operations that accumulate errors

func MakeValidationErrors added in v2.1.19

func MakeValidationErrors(errors Errors) error

MakeValidationErrors converts a collection of validation errors into a single error. It wraps the Errors slice in a ValidationErrors struct that implements the error interface. This is useful for converting validation failures into standard Go errors.

Parameters:

  • errors: A slice of ValidationError pointers representing validation failures

Returns:

  • An error that contains all the validation errors and can be used with standard error handling

Example:

errors := Errors{
    &ValidationError{Value: "abc", Messsage: "expected number"},
    &ValidationError{Value: nil, Messsage: "required field"},
}
err := MakeValidationErrors(errors)
fmt.Println(err) // Output: ValidationErrors: 2 errors

Types

type Context

type Context = []ContextEntry

Context is a stack of ContextEntry values representing the path through nested structures during validation. Used to provide detailed error messages that show exactly where in a nested structure a validation failure occurred.

The context builds up as validation descends into nested structures:

  • [] - root level
  • [{Key: "user"}] - inside user object
  • [{Key: "user"}, {Key: "address"}] - inside user.address
  • [{Key: "user"}, {Key: "address"}, {Key: "zipCode"}] - at user.address.zipCode

Example:

ctx := Context{
    {Key: "user", Type: "User"},
    {Key: "address", Type: "Address"},
    {Key: "zipCode", Type: "string"},
}
// Represents path: user.address.zipCode

type ContextEntry

type ContextEntry struct {
	Key    string // The key or field name (for objects/maps)
	Type   string // The expected type name
	Actual any    // The actual value being validated
}

ContextEntry represents a single entry in the validation context path. It tracks the location and type information during nested validation, enabling precise error reporting with full path information.

Fields:

  • Key: The key or field name (e.g., "email", "address", "items[0]")
  • Type: The expected type name (e.g., "string", "int", "User")
  • Actual: The actual value being validated (for error reporting)

Example:

entry := ContextEntry{
    Key:    "user.email",
    Type:   "string",
    Actual: 12345,
}

type Either

type Either[E, A any] = either.Either[E, A]

Either represents a value that can be one of two types: Left (error) or Right (success). This is an alias for either.Either[E, A], a disjoint union type.

In the validation context:

  • Left[E]: Contains error information of type E
  • Right[A]: Contains a successfully validated value of type A

type Endomorphism added in v2.2.6

type Endomorphism[A any] = endomorphism.Endomorphism[A]

Endomorphism represents a function from a type to itself: func(A) A. This is an alias for endomorphism.Endomorphism[A].

In the validation context, endomorphisms are used with LetL to transform values within a validation context using pure functions.

Example:

double := func(x int) int { return x * 2 }  // Endomorphism[int]
result := LetL(lens, double)(Success(21))   // Success(42)

type Errors

type Errors = []*ValidationError

Errors is a collection of validation errors. This type is used to accumulate multiple validation failures, allowing all errors to be reported at once rather than failing fast.

Example:

errors := Errors{
    &ValidationError{Value: "", Messsage: "name is required"},
    &ValidationError{Value: "invalid", Messsage: "invalid email"},
    &ValidationError{Value: -1, Messsage: "age must be positive"},
}

type Kleisli

type Kleisli[A, B any] = Reader[A, Validation[B]]

Kleisli represents a function from A to a validated B. It's a Reader that takes an input A and produces a Validation[B]. This is the fundamental building block for composable validation operations.

Type: func(A) Validation[B]

Kleisli arrows can be composed using Chain/Bind operations to build complex validation pipelines from simple validation functions.

Example:

validatePositive := func(x int) Validation[int] {
    if x > 0 {
        return Success(x)
    }
    return Failures[int](/* error */)
}

validateEven := func(x int) Validation[int] {
    if x%2 == 0 {
        return Success(x)
    }
    return Failures[int](/* error */)
}

// Compose validations
validatePositiveEven := Chain(validateEven)(Success(42))

type Monoid

type Monoid[A any] = monoid.Monoid[A]

Monoid represents an algebraic structure with an associative binary operation and an identity element. This is an alias for monoid.Monoid[A].

In the validation context, monoids are used to combine validation results:

  • ApplicativeMonoid: Combines successful validations using the monoid operation
  • AlternativeMonoid: Provides fallback behavior for failed validations

Example:

import N "github.com/IBM/fp-go/v2/number"

intAdd := N.MonoidSum[int]()
m := ApplicativeMonoid(intAdd)
result := m.Concat(Success(5), Success(3))  // Success(8)

func ApplicativeMonoid

func ApplicativeMonoid[A any](m Monoid[A]) Monoid[Validation[A]]

ApplicativeMonoid creates a Monoid instance for Validation[A] given a Monoid for A. This allows combining validation results where the success values are also combined using the provided monoid. If any validation fails, all errors are accumulated.

The resulting monoid:

  • Empty: Returns a successful validation with the empty value from the inner monoid
  • Concat: Combines two validations:
  • Both success: Combines values using the inner monoid
  • Any failure: Accumulates all errors

Example:

import "github.com/IBM/fp-go/v2/string"

// Create a monoid for validations of strings
m := ApplicativeMonoid(string.Monoid)

v1 := Success("Hello")
v2 := Success(" World")
combined := m.Concat(v1, v2) // Success("Hello World")

v3 := Failures[string](someErrors)
failed := m.Concat(v1, v3) // Failures with accumulated errors

func ErrorsMonoid

func ErrorsMonoid() Monoid[Errors]

ErrorsMonoid returns a Monoid instance for Errors (array of ValidationError pointers). The monoid concatenates error arrays, with an empty array as the identity element. This is used internally by the applicative operations to accumulate validation errors.

Example:

m := ErrorsMonoid()
combined := m.Concat(errors1, errors2) // Concatenates both error arrays
empty := m.Empty()                      // Returns empty error array

type Operator

type Operator[A, B any] = Kleisli[Validation[A], B]

Operator represents a validation transformation that takes a validated A and produces a validated B. It's a specialized Kleisli arrow for composing validation operations where the input is already a Validation[A].

Type: func(Validation[A]) Validation[B]

Operators are used to transform and compose validation results, enabling functional composition of validation pipelines.

Example:

// Transform a validated int to a validated string
intToString := Map(func(x int) string {
    return strconv.Itoa(x)
})  // Operator[int, string]

result := intToString(Success(42))  // Success("42")

func Ap

func Ap[B, A any](fa Validation[A]) Operator[func(A) B, B]

Ap applies a validation containing a function to a validation containing a value. This is the applicative apply operation that accumulates errors from both validations. If either validation fails, all errors are collected. If both succeed, the function is applied.

This enables combining multiple validations while collecting all errors:

Example:

// Validate multiple fields and collect all errors
validateUser := Ap(Ap(Of(func(name string) func(age int) User {
	return func(age int) User { return User{name, age} }
}))(validateName))(validateAge)

func ApS added in v2.2.6

func ApS[S1, S2, T any](
	setter func(T) func(S1) S2,
	fa Validation[T],
) Operator[S1, S2]

ApS attaches a value to a context S1 to produce a context S2 by considering the context and the value concurrently. This uses the applicative functor pattern, allowing parallel composition.

IMPORTANT: Unlike Bind which fails fast, ApS aggregates ALL validation errors from both the context and the value. If both validations fail, all errors are collected and returned together. This is useful for validating multiple independent fields and reporting all errors at once.

Example:

type State struct { x int; y int }
result := F.Pipe2(
    Do(State{}),
    ApS(func(x int) func(State) State {
        return func(s State) State { s.x = x; return s }
    }, Success(42)),
)

Error aggregation example:

stateFailure := Failures[State](Errors{&ValidationError{Messsage: "state error"}})
valueFailure := Failures[int](Errors{&ValidationError{Messsage: "value error"}})
result := ApS(setter, valueFailure)(stateFailure)
// Result contains BOTH errors: ["state error", "value error"]

func ApSL added in v2.2.6

func ApSL[S, T any](
	lens L.Lens[S, T],
	fa Validation[T],
) Operator[S, S]

ApSL attaches a value to a context using a lens-based setter. This is a convenience function that combines ApS with a lens, allowing you to use optics to update nested structures in a more composable way.

IMPORTANT: Like ApS, this function aggregates ALL validation errors. If both the context and the value fail validation, all errors are collected and returned together. This enables comprehensive error reporting for complex nested structures.

The lens parameter provides both the getter and setter for a field within the structure S. This eliminates the need to manually write setter functions.

Example:

type Address struct {
    Street string
    City   string
}

type Person struct {
    Name    string
    Address Address
}

// Create a lens for the Address field
addressLens := lens.MakeLens(
    func(p Person) Address { return p.Address },
    func(p Person, a Address) Person { p.Address = a; return p },
)

// Use ApSL to update the address
result := F.Pipe2(
    Success(Person{Name: "Alice"}),
    ApSL(
        addressLens,
        Success(Address{Street: "Main St", City: "NYC"}),
    ),
)

func Bind added in v2.2.6

func Bind[S1, S2, A any](
	setter func(A) func(S1) S2,
	f Kleisli[S1, A],
) Operator[S1, S2]

Bind attaches the result of a computation to a context S1 to produce a context S2. This is used in do-notation style to sequentially build up a context.

Example:

type State struct { x int; y int }
result := F.Pipe2(
    Do(State{}),
    Bind(func(x int) func(State) State {
        return func(s State) State { s.x = x; return s }
    }, func(s State) Validation[int] { return Success(42) }),
)

func BindL added in v2.2.6

func BindL[S, T any](
	lens L.Lens[S, T],
	f Kleisli[T, T],
) Operator[S, S]

BindL attaches the result of a computation to a context using a lens-based setter. This is a convenience function that combines Bind with a lens, allowing you to use optics to update nested structures based on their current values.

The lens parameter provides both the getter and setter for a field within the structure S. The computation function f receives the current value of the focused field and returns a Validation that produces the new value.

Unlike ApSL, BindL uses monadic sequencing, meaning the computation f can depend on the current value of the focused field.

Example:

type Counter struct {
    Value int
}

valueLens := lens.MakeLens(
    func(c Counter) int { return c.Value },
    func(c Counter, v int) Counter { c.Value = v; return c },
)

// Increment the counter, but fail if it would exceed 100
increment := func(v int) Validation[int] {
    if v >= 100 {
        return Failures[int](Errors{&ValidationError{Messsage: "exceeds limit"}})
    }
    return Success(v + 1)
}

result := F.Pipe1(
    Success(Counter{Value: 42}),
    BindL(valueLens, increment),
) // Success(Counter{Value: 43})

func BindTo added in v2.2.6

func BindTo[S1, T any](
	setter func(T) S1,
) Operator[T, S1]

BindTo initializes a new state S1 from a value T. This is typically used as the first operation after creating a Validation value.

Example:

type State struct { value int }
result := F.Pipe1(
    Success(42),
    BindTo(func(x int) State { return State{value: x} }),
)

func Chain added in v2.1.21

func Chain[A, B any](f Kleisli[A, B]) Operator[A, B]

func Let added in v2.2.6

func Let[S1, S2, B any](
	key func(B) func(S1) S2,
	f func(S1) B,
) Operator[S1, S2]

Let attaches the result of a pure computation to a context S1 to produce a context S2. Unlike Bind, the computation function returns a plain value, not an Option.

Example:

type State struct { x int; computed int }
result := F.Pipe2(
    Do(State{x: 5}),
    Let(func(c int) func(State) State {
        return func(s State) State { s.computed = c; return s }
    }, func(s State) int { return s.x * 2 }),
)

func LetL added in v2.2.6

func LetL[S, T any](
	lens L.Lens[S, T],
	f Endomorphism[T],
) Operator[S, S]

LetL attaches the result of a pure computation to a context using a lens-based setter. This is a convenience function that combines Let with a lens, allowing you to use optics to update nested structures with pure transformations.

The lens parameter provides both the getter and setter for a field within the structure S. The transformation function f receives the current value of the focused field and returns the new value directly (not wrapped in Validation).

This is useful for pure transformations that cannot fail, such as mathematical operations, string manipulations, or other deterministic updates.

Example:

type Counter struct {
    Value int
}

valueLens := lens.MakeLens(
    func(c Counter) int { return c.Value },
    func(c Counter, v int) Counter { c.Value = v; return c },
)

// Double the counter value
double := func(v int) int { return v * 2 }

result := F.Pipe1(
    Success(Counter{Value: 21}),
    LetL(valueLens, double),
) // Success(Counter{Value: 42})

func LetTo added in v2.2.6

func LetTo[S1, S2, B any](
	key func(B) func(S1) S2,
	b B,
) Operator[S1, S2]

LetTo attaches a constant value to a context S1 to produce a context S2.

Example:

type State struct { x int; name string }
result := F.Pipe2(
    Do(State{x: 5}),
    LetTo(func(n string) func(State) State {
        return func(s State) State { s.name = n; return s }
    }, "example"),
)

func LetToL added in v2.2.6

func LetToL[S, T any](
	lens L.Lens[S, T],
	b T,
) Operator[S, S]

LetToL attaches a constant value to a context using a lens-based setter. This is a convenience function that combines LetTo with a lens, allowing you to use optics to set nested fields to specific values.

The lens parameter provides the setter for a field within the structure S. Unlike LetL which transforms the current value, LetToL simply replaces it with the provided constant value b.

This is useful for resetting fields, initializing values, or setting fields to predetermined constants.

Example:

type Config struct {
    Debug   bool
    Timeout int
}

debugLens := lens.MakeLens(
    func(c Config) bool { return c.Debug },
    func(c Config, d bool) Config { c.Debug = d; return c },
)

result := F.Pipe1(
    Success(Config{Debug: true, Timeout: 30}),
    LetToL(debugLens, false),
) // Success(Config{Debug: false, Timeout: 30})

func Map

func Map[A, B any](f func(A) B) Operator[A, B]

Map transforms the value inside a successful validation using the provided function. If the validation is a failure, the errors are preserved unchanged. This is the functor map operation for Validation.

Example:

doubled := Map(func(x int) int { return x * 2 })(Of(21))
// Result: Success(42)

type Reader

type Reader[R, A any] = reader.Reader[R, A]

Reader represents a computation that depends on an environment R and produces a value A. This is an alias for reader.Reader[R, A], which is func(R) A.

In the validation context, Reader is used for context-dependent validation operations where the validation logic needs access to the current validation context path.

Example:

validateWithContext := func(ctx Context) Validation[int] {
    // Use ctx to provide detailed error messages
    return Success(42)
}

func FailureWithError

func FailureWithError[T any](value any, message string) Reader[error, Reader[Context, Validation[T]]]

FailureWithError creates a validation failure with a custom message and underlying cause. Returns a Reader that takes an error, then a Context, and produces a Validation[T] failure. This is useful for wrapping errors from other operations while maintaining validation context.

Example:

fail := FailureWithError[int]("abc", "parse failed")
result := fail(parseErr)([]ContextEntry{{Key: "count", Type: "int"}})

func FailureWithMessage

func FailureWithMessage[T any](value any, message string) Reader[Context, Validation[T]]

FailureWithMessage creates a validation failure with a custom message. Returns a Reader that takes a Context and produces a Validation[T] failure. This is useful for creating context-aware validation errors.

Example:

fail := FailureWithMessage[int]("abc", "expected integer")
result := fail([]ContextEntry{{Key: "age", Type: "int"}})

type Result added in v2.1.19

type Result[A any] = result.Result[A]

Result represents a computation that may succeed with a value of type A or fail with an error. This is an alias for result.Result[A], which is Either[error, A].

Used for converting validation results to standard Go error handling patterns.

func ToResult added in v2.1.19

func ToResult[T any](val Validation[T]) Result[T]

ToResult converts a Validation[T] to a Result[T]. It transforms the Left side (validation errors) into a standard error using MakeValidationErrors, while preserving the Right side (successful value) unchanged. This is useful for integrating validation results with code that expects Result types.

Type Parameters:

  • T: The type of the successfully validated value

Parameters:

  • val: A Validation[T] which is Either[Errors, T]

Returns:

  • A Result[T] which is Either[error, T], with validation errors converted to a single error

Example:

validation := Success[int](42)
result := ToResult(validation) // Result containing 42

validation := Failures[int](Errors{&ValidationError{Messsage: "invalid"}})
result := ToResult(validation) // Result containing ValidationErrors error

type Validation

type Validation[A any] = Either[Errors, A]

Validation represents the result of a validation operation. It's an Either type where:

  • Left(Errors): Validation failed with one or more errors
  • Right(A): Successfully validated value of type A

This type supports applicative operations, allowing multiple validations to be combined while accumulating all errors rather than failing fast.

Example:

// Success case
valid := Success(42)  // Right(42)

// Failure case
invalid := Failures[int](Errors{
    &ValidationError{Messsage: "must be positive"},
})  // Left([...])

// Combining validations (accumulates all errors)
result := Ap(Ap(Of(func(x int) func(y int) int {
    return func(y int) int { return x + y }
}))(validateX))(validateY)

func Do added in v2.2.6

func Do[S any](
	empty S,
) Validation[S]

Do creates an empty context of type S to be used with the Bind operation. This is the starting point for building up a context using do-notation style.

Example:

type Result struct {
    x int
    y string
}
result := Do(Result{})

func Failures

func Failures[T any](err Errors) Validation[T]

Failures creates a validation failure from a collection of errors. Returns a Left Either containing the errors.

func MonadAp added in v2.1.21

func MonadAp[B, A any](fab Validation[func(A) B], fa Validation[A]) Validation[B]

func MonadChain added in v2.1.21

func MonadChain[A, B any](fa Validation[A], f Kleisli[A, B]) Validation[B]

func MonadMap added in v2.1.21

func MonadMap[A, B any](fa Validation[A], f func(A) B) Validation[B]

func Of

func Of[A any](a A) Validation[A]

Of creates a successful validation result containing the given value. This is the pure/return operation for the Validation monad.

Example:

valid := Of(42) // Validation[int] containing 42

func Success

func Success[T any](value T) Validation[T]

Success creates a successful validation result. Returns a Right Either containing the validated value.

type ValidationError

type ValidationError struct {
	Value    any     // The value that failed validation
	Context  Context // The path to the value in nested structures
	Messsage string  // Human-readable error message
	Cause    error   // Optional underlying error cause
}

ValidationError represents a single validation failure with full context information. It implements the error interface and provides detailed information about what failed, where it failed, and why it failed.

Fields:

  • Value: The actual value that failed validation
  • Context: The path to the value in nested structures (e.g., user.address.zipCode)
  • Messsage: Human-readable error description
  • Cause: Optional underlying error that caused the validation failure

The ValidationError type implements:

  • error interface: For standard Go error handling
  • fmt.Formatter: For custom formatting with %v, %+v
  • slog.LogValuer: For structured logging with slog

Example:

err := &ValidationError{
    Value:    "not-an-email",
    Context:  []ContextEntry{{Key: "user"}, {Key: "email"}},
    Messsage: "invalid email format",
    Cause:    nil,
}
fmt.Printf("%v", err)   // at user.email: invalid email format
fmt.Printf("%+v", err)  // at user.email: invalid email format
                        //   value: "not-an-email"

func (*ValidationError) Error

func (v *ValidationError) Error() string

Error implements the error interface for ValidationError. Returns a generic error message.

func (*ValidationError) Format

func (v *ValidationError) Format(s fmt.State, verb rune)

Format implements fmt.Formatter for custom formatting of ValidationError. It includes the context path, message, and optionally the cause error. Supports verbs: %s, %v, %+v (with additional details)

func (*ValidationError) LogValue added in v2.1.21

func (v *ValidationError) LogValue() slog.Value

LogValue implements the slog.LogValuer interface for ValidationError. It provides structured logging representation of the validation error. Returns a slog.Value containing the error details as a group with message, value, context path, and optional cause.

This method is called automatically when logging a ValidationError with slog.

Example:

err := &ValidationError{Value: "abc", Messsage: "expected number"}
slog.Error("validation failed", "error", err)
// Logs: error={message="expected number" value="abc"}

func (*ValidationError) String

func (v *ValidationError) String() string

String returns a simple string representation of the validation error. Returns the error message prefixed with "ValidationError: ".

func (*ValidationError) Unwrap

func (v *ValidationError) Unwrap() error

Unwrap returns the underlying cause error if present. This allows ValidationError to work with errors.Is and errors.As.

Jump to

Keyboard shortcuts

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