bf9395e022
CI / results (push) Blocked by required conditions
CI / license-header (push) Has been skipped
CI / e2e-dry-run (push) Has been skipped
CI / e2e-live (push) Waiting to run
CI / fast-gate (push) Failing after 0s
Test PR Label Logic / test-pr-labels (push) Failing after 1s
Skill Format Check / check-format (push) Failing after 2s
CI / security (push) Failing after 5s
CI / unit-test (push) Has been skipped
CI / lint (push) Has been skipped
CI / script-test (push) Has been skipped
CI / deterministic-gate (push) Has been skipped
CI / coverage (push) Has been skipped
CI / deadcode (push) Waiting to run
97 lines
2.8 KiB
Go
97 lines
2.8 KiB
Go
// Copyright (c) 2026 Lark Technologies Pte. Ltd.
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
package errs_test
|
|
|
|
import (
|
|
"encoding/json"
|
|
"errors"
|
|
"fmt"
|
|
"testing"
|
|
|
|
"github.com/larksuite/cli/errs"
|
|
)
|
|
|
|
func TestMarkRawNilReturnsNil(t *testing.T) {
|
|
if got := errs.MarkRaw(nil); got != nil {
|
|
t.Fatalf("MarkRaw(nil) = %v, want nil", got)
|
|
}
|
|
}
|
|
|
|
func TestIsRaw(t *testing.T) {
|
|
base := fmt.Errorf("boom")
|
|
|
|
if !errs.IsRaw(errs.MarkRaw(base)) {
|
|
t.Errorf("IsRaw(MarkRaw(err)) = false, want true")
|
|
}
|
|
if errs.IsRaw(base) {
|
|
t.Errorf("IsRaw(bare err) = true, want false")
|
|
}
|
|
if errs.IsRaw(nil) {
|
|
t.Errorf("IsRaw(nil) = true, want false")
|
|
}
|
|
|
|
// Raw marking survives further wrapping above it in the chain.
|
|
wrapped := fmt.Errorf("outer: %w", errs.MarkRaw(base))
|
|
if !errs.IsRaw(wrapped) {
|
|
t.Errorf("IsRaw(wrap(MarkRaw(err))) = false, want true")
|
|
}
|
|
}
|
|
|
|
func TestMarkRawPreservesErrorMessage(t *testing.T) {
|
|
base := fmt.Errorf("boom")
|
|
if got := errs.MarkRaw(base).Error(); got != "boom" {
|
|
t.Fatalf("MarkRaw(err).Error() = %q, want %q", got, "boom")
|
|
}
|
|
}
|
|
|
|
func TestMarkRawPreservesErrorsIsChain(t *testing.T) {
|
|
sentinel := errors.New("sentinel")
|
|
wrapped := fmt.Errorf("ctx: %w", sentinel)
|
|
|
|
if !errors.Is(errs.MarkRaw(wrapped), sentinel) {
|
|
t.Fatalf("errors.Is(MarkRaw(err), sentinel) = false, want true")
|
|
}
|
|
}
|
|
|
|
func TestProblemOfPunchesThroughMarkRaw(t *testing.T) {
|
|
typed := errs.NewValidationError(errs.SubtypeInvalidArgument, "bad flag")
|
|
raw := errs.MarkRaw(typed)
|
|
|
|
p, ok := errs.ProblemOf(raw)
|
|
if !ok {
|
|
t.Fatalf("ProblemOf(MarkRaw(typed)) ok = false, want true")
|
|
}
|
|
if p.Category != errs.CategoryValidation {
|
|
t.Errorf("ProblemOf(MarkRaw(typed)).Category = %v, want %v", p.Category, errs.CategoryValidation)
|
|
}
|
|
|
|
// errors.As still finds the concrete typed error through the raw wrapper.
|
|
var ve *errs.ValidationError
|
|
if !errors.As(raw, &ve) {
|
|
t.Errorf("errors.As(MarkRaw(typed), *ValidationError) = false, want true")
|
|
}
|
|
}
|
|
|
|
// TestMarkRawUnwrapsToInnerTypedError pins the envelope-serialization
|
|
// contract: UnwrapTypedError must return the inner concrete typed error,
|
|
// not the rawPassthrough wrapper. The wrapper has no exported fields, so if it
|
|
// were returned the JSON envelope would marshal to an empty "{}" error.
|
|
func TestMarkRawUnwrapsToInnerTypedError(t *testing.T) {
|
|
base := errs.NewValidationError(errs.SubtypeInvalidArgument, "bad flag")
|
|
typed, ok := errs.UnwrapTypedError(errs.MarkRaw(base))
|
|
if !ok {
|
|
t.Fatal("UnwrapTypedError(MarkRaw(typed)) must find a typed error")
|
|
}
|
|
out, err := json.Marshal(typed)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if string(out) == "{}" {
|
|
t.Fatalf("UnwrapTypedError returned the opaque rawPassthrough wrapper; envelope would be empty: %s", out)
|
|
}
|
|
if got := errs.CategoryOf(typed); got != errs.CategoryValidation {
|
|
t.Fatalf("unwrapped category = %q, want validation", got)
|
|
}
|
|
}
|