Skip to content

Constants and Errors ​

Error Variables ​

Primary Errors ​

go
var (
    // Basic errors
    ErrInvalidJSON     = errors.New("invalid JSON format")
    ErrPathNotFound    = errors.New("path not found")
    ErrTypeMismatch    = errors.New("type mismatch")
    ErrInvalidPath     = errors.New("invalid path format")
    ErrProcessorClosed = errors.New("processor is closed")

    // Limit errors
    ErrSizeLimit        = errors.New("size limit exceeded")
    ErrDepthLimit       = errors.New("depth limit exceeded")
    ErrConcurrencyLimit = errors.New("concurrency limit exceeded") // Returned when controlled operations (Get/Set/Delete, etc.) reach MaxConcurrency

    // Security and validation errors
    ErrSecurityViolation = errors.New("security violation detected")
    ErrDuplicateKey      = errors.New("duplicate object key")
    ErrUnsupportedPath   = errors.New("unsupported path operation") // Deprecated: not returned by any operation today, reserved

    // Resource and performance errors (both Deprecated: not returned by any operation today, kept for future use)
    ErrOperationTimeout  = errors.New("operation timeout")
    ErrResourceExhausted = errors.New("system resources exhausted")
)

Trigger Scenarios at a Glance ​

Typical trigger scenarios for each sentinel error, to help you write recovery logic per error branch:

ErrorTypical triggerSuggested handling
ErrInvalidJSONInput is not valid JSON (trailing characters, unclosed brackets, etc.)Reject the input; check the source
ErrPathNotFoundThe path of a Get does not exist in the dataCommon in practice; fall back to a default
ErrTypeMismatchPath exists but the type is wrong (e.g. [0] on a string path)Check your data-structure assumptions
ErrInvalidPathPath syntax error (CompilePath / path parsing failure)Fix the path expression
ErrProcessorClosedMethods called after Close() (or while closing)Check the lifecycle; pre-check with IsClosed
ErrSizeLimitInput exceeds MaxJSONSize / MaxSecurityValidationSizeRaise the limit or reject oversized input
ErrDepthLimitNesting exceeds MaxNestingDepthSecurityReject deeply nested input (possibly an attack)
ErrConcurrencyLimitControlled-operation concurrency exceeds MaxConcurrencyReduce concurrency or raise the limit
ErrSecurityViolationDangerous pattern hit, or MaxObjectKeys/MaxArrayElements exceededWrite an audit log and reject
ErrDuplicateKeyDuplicate keys present in an input object while Config.DetectDuplicateKeys is enabledReject the input (when off by default, the last duplicate key wins, consistent with encoding/json)
ErrUnsupportedPathReserved, no operation currently returns it (deprecated; unsupported segments surface as ErrInvalidPath or ErrTypeMismatch)No handling needed in error branches
ErrOperationTimeoutReserved, no operation currently returns it (deprecated)No handling needed in error branches
ErrResourceExhaustedReserved, no operation currently returns it (deprecated)No handling needed in error branches

Three deprecated sentinels

No operation currently returns ErrOperationTimeout, ErrResourceExhausted, or ErrUnsupportedPath; they are kept for future releases only — no need to handle them in error branches.

Error Checking ​

Use errors.Is to check error types:

go
val, err := json.Get(data, "user.name")
if err != nil {
    if errors.Is(err, json.ErrPathNotFound) {
        // Path does not exist
        fmt.Println("Path not found")
    } else if errors.Is(err, json.ErrTypeMismatch) {
        // Type mismatch
        fmt.Println("Type mismatch")
    } else if errors.Is(err, json.ErrInvalidJSON) {
        // Malformed JSON
        fmt.Println("Invalid JSON")
    }
}

The JsonsError Type ​

Struct Definition ​

go
type JsonsError struct {
    Op      string `json:"op"`      // Operation name
    Path    string `json:"path"`    // Path where the error occurred
    Message string `json:"message"` // Human-readable error message
    Err     error  `json:"err"`     // Underlying error
}

Field Reference

FieldTypeDescription
OpstringName of the operation that failed
PathstringJSON path where the error occurred
MessagestringHuman-readable error message
ErrerrorUnderlying error (may be nil); Unwrap supports errors.Is / errors.As chain traversal

Methods ​

go
func (e *JsonsError) Error() string   // "JSON <op> failed at path '<path>': <msg> (caused by: ...)"
func (e *JsonsError) Unwrap() error   // Returns the underlying error (supports errors.As/Is chains)
func (e *JsonsError) Is(target error) bool

Matching rules of Is:

  • When the target is a *JsonsError, the three fields Op, Path, and Err are compared field by field (Message is derived information and deliberately excluded from comparison)
  • When the target is another error (e.g. a sentinel), it degrades to errors.Is on the underlying Err — so errors.Is(err, json.ErrPathNotFound) still holds for a wrapped JsonsError

Usage Example ​

go
val, err := json.Get(data, "complex.path[0]")
if err != nil {
    var jsonErr *json.JsonsError
    if errors.As(err, &jsonErr) {
        fmt.Printf("Operation: %s\n", jsonErr.Op)
        fmt.Printf("Path: %s\n", jsonErr.Path)
        fmt.Printf("Message: %s\n", jsonErr.Message)
        if jsonErr.Err != nil {
            fmt.Printf("Cause: %v\n", jsonErr.Err)
        }
    }
}

Error Helper Functions ​

Beyond the error types above, the library provides two error-handling helpers (full description in Helper Functions):

FunctionSignatureDescription
SafeErrorfunc SafeError(err error) stringReturns a client-safe error message, omitting internal details such as path names (CWE-209)
RedactedPathfunc RedactedPath(path string) stringReturns a redacted path (non-empty paths masked as "***"), for logs and error responses

Configuration Presets ​

Default Value Constants ​

go
const (
    // Size limits
    DefaultMaxJSONSize     = 100 * 1024 * 1024  // 100MB
    DefaultMaxNestingDepth = 200
    DefaultMaxPathDepth    = 50
    DefaultMaxDepth        = 100                 // Default encode/decode nesting depth (Config.MaxDepth)
    DefaultMaxConcurrency  = 50

    // Security limits
    DefaultMaxSecuritySize   = 10 * 1024 * 1024  // 10MB
    DefaultMaxObjectKeys     = 100000
    DefaultMaxArrayElements  = 100000
    DefaultMaxBatchSize      = 2000
    DefaultParallelThreshold = 10

    // Cache
    DefaultCacheTTL = 5 * time.Minute
)

Constants vs Config Fields ​

ConstantDefaultConfig fieldDescription
DefaultMaxJSONSize100MBMaxJSONSizeSize cap for a single JSON input
DefaultMaxNestingDepth200MaxNestingDepthSecurityJSON nesting depth cap
DefaultMaxPathDepth50MaxPathDepthCap on path segment count (the depth of a.b.c.d...)
DefaultMaxDepth100MaxDepthDefault nesting depth for encode/decode (Marshal/Unmarshal)
DefaultMaxConcurrency50MaxConcurrencyCap on concurrent operations
DefaultMaxSecuritySize10MBMaxSecurityValidationSizeDocuments above this size fall back to sampled security checks
DefaultMaxObjectKeys100000MaxObjectKeysObject key count cap
DefaultMaxArrayElements100000MaxArrayElementsArray element count cap
DefaultMaxBatchSize2000MaxBatchSizeCap on operations per ProcessBatch call; exceeding it returns ErrSizeLimit
DefaultParallelThreshold10ParallelThresholdParallel processing threshold: below this operation count, processing is sequential
DefaultCacheTTL5 minutesCacheTTLCache entry lifetime

Configuration Preset Functions ​

DefaultConfig ​

Signature: func DefaultConfig() Config

Returns the default configuration.

go
cfg := json.DefaultConfig()
processor, err := json.New(cfg)
if err != nil {
    panic(err)
}
defer processor.Close()

SecurityConfig ​

Signature: func SecurityConfig() Config

Returns the security configuration, suitable for handling untrusted input.

go
// Recommended for:
// - Public APIs and web services
// - User-submitted data
// - External webhooks
// - Authentication endpoints
// - Financial data processing
cfg := json.SecurityConfig()
processor, err := json.New(cfg)
if err != nil {
    panic(err)
}
defer processor.Close()

Security configuration characteristics:

  • Full security scanning
  • Strict mode
  • Conservative limit values
  • Cache enabled

PrettyConfig ​

Signature: func PrettyConfig() Config

Returns the pretty-print configuration.

go
result, err := json.Encode(data, json.PrettyConfig())

Merge Mode Constants ​

go
// MergeMode is the merge mode type (exported from the internal package)
type MergeMode = internal.MergeMode

const (
    // MergeUnion - union merge (default)
    // Objects: merge all keys; conflicting values take the overriding value
    // Arrays: merge all elements and deduplicate
    MergeUnion = internal.MergeUnion

    // MergeIntersection - intersection merge
    // Objects: keep only shared keys
    // Arrays: keep only shared elements
    MergeIntersection = internal.MergeIntersection

    // MergeDifference - difference merge
    // Objects: keep only keys present in the base but absent from the override
    // Arrays: keep only elements present in the base but absent from the override
    MergeDifference = internal.MergeDifference
)

The PathSegment Type ​

PathSegment is the path-segment type exported from the internal package, representing the components of a parsed path.

go
type PathSegment = internal.PathSegment

An alias over an internal type

PathSegment is a type alias of internal.PathSegment. Its fields, field types (PathSegmentType, PathSegmentFlags), and methods belong to the internal package, are not exported as public API, and may change between versions — do not depend on its internals in business code.

  • When implementing custom path syntax, return []PathSegment from the ParsePath method of the PathParser interface.
  • For pre-compiled paths, use Processor.CompilePath, which returns *CompiledPath.

Security Pattern Levels ​

go
type PatternLevel int

const (
    // PatternLevelCritical - critical risk, always blocks the operation
    PatternLevelCritical PatternLevel = iota

    // PatternLevelWarning - warning level, blocked in strict mode
    PatternLevelWarning

    // PatternLevelInfo - informational level, logged only
    PatternLevelInfo
)

The DangerousPattern Struct ​

go
type DangerousPattern struct {
    Pattern string       // Substring to detect
    Name    string       // Human-readable description of the security risk
    Level   PatternLevel // Handling level
}

Error-Handling Best Practices ​

Check types with errors.Is ​

go
result, err := json.Get(data, path)
if errors.Is(err, json.ErrPathNotFound) {
    return defaultValue
}
if errors.Is(err, json.ErrTypeMismatch) {
    return defaultValue
}

Get details with errors.As ​

go
var jsonErr *json.JsonsError
if errors.As(err, &jsonErr) {
    log.Printf("Operation %s failed at path %s: %s",
        jsonErr.Op, jsonErr.Path, jsonErr.Message)
}

Error wrapping ​

go
val := json.GetString(data, path)
if val == "" {
    return fmt.Errorf("getting config %s returned an empty value", path)
}

See Also ​