From 8daca65fc3a52a61d64929a0d2333193950573c4 Mon Sep 17 00:00:00 2001 From: resolvicomai Date: Thu, 21 May 2026 09:14:09 -0300 Subject: [PATCH] fix(i18n): wrap parse error cause (#1319) ## What? - Wrap the JSON parser source error with `%w` instead of rendering it with `%v`. - Add regression coverage that preserves both `ErrParseFailed` and the original `json.SyntaxError` in the error chain. Closes #1050 ## Why? The i18n parser already wraps `ErrParseFailed`, but the underlying JSON parse error was converted to text. That made `errors.As` unable to recover the original cause from callers that need to inspect it. --- i18n/parser.go | 2 +- i18n/parser_test.go | 23 +++++++++++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) create mode 100644 i18n/parser_test.go diff --git a/i18n/parser.go b/i18n/parser.go index 1b8467a188e2260e372ea6fa4ce4457adae07a17..37cdc8a0855b39a0f8162148a6d27a2473f1f152 100644 --- a/i18n/parser.go +++ b/i18n/parser.go @@ -15,7 +15,7 @@ type TranslationFile struct { func ParseJSON(data []byte) (MessageMap, error) { var file TranslationFile if err := json.Unmarshal(data, &file); err != nil { - return nil, fmt.Errorf("%w: %v", ErrParseFailed, err) + return nil, fmt.Errorf("%w: %w", ErrParseFailed, err) } messages := make(MessageMap) diff --git a/i18n/parser_test.go b/i18n/parser_test.go new file mode 100644 index 0000000000000000000000000000000000000000..339fbf8310a597346629e6297fc267429362df89 --- /dev/null +++ b/i18n/parser_test.go @@ -0,0 +1,23 @@ +package i18n + +import ( + "encoding/json" + "errors" + "testing" +) + +func TestParseJSONWrapsSyntaxError(t *testing.T) { + _, err := ParseJSON([]byte(`{"language":"en","messages":`)) + if err == nil { + t.Fatal("ParseJSON() error = nil, want parse error") + } + + if !errors.Is(err, ErrParseFailed) { + t.Fatalf("ParseJSON() error = %v, want ErrParseFailed in chain", err) + } + + var syntaxErr *json.SyntaxError + if !errors.As(err, &syntaxErr) { + t.Fatalf("ParseJSON() error = %v, want json.SyntaxError in chain", err) + } +}