Skip to content

fix: AnErr emits invalid JSON when the error is an ObjectMarshaler - #123

Open
youdie006 wants to merge 1 commit into
phuslu:masterfrom
youdie006:fix/110-anerr-objectmarshaler-invalid-json
Open

fix: AnErr emits invalid JSON when the error is an ObjectMarshaler#123
youdie006 wants to merge 1 commit into
phuslu:masterfrom
youdie006:fix/110-anerr-objectmarshaler-invalid-json

Conversation

@youdie006

Copy link
Copy Markdown

Fixes #110.

Problem

When an error passed to .Err(err) / .AnErr(key, err) also implements ObjectMarshaler, the logger emits invalid JSON. AnErr writes the "error": key and then calls o.MarshalObject(e) directly. Each field method in MarshalObject prepends a comma (e.g. ,"code":500), so the buffer ends up as:

"error":,"code":500,"message":"boom"

The leading comma is stray and the object's fields leak to the top level; json.Valid() returns false.

Root cause

AnErr does not wrap the marshaler's output in braces or fix the leading comma. The library's own reference implementation Object() already does this correctly: it records n := len(e.buf) before calling MarshalObject, then rewrites the first byte (the stray comma) to { and appends }.

Fix

Mirror the existing Object() convention inside AnErr's ObjectMarshaler branch (~7 lines). The non-ObjectMarshaler string path is unchanged, and an empty marshaler now yields null (same as Object()).

Tests

Added TestAnErrObjectMarshaler: an error type implementing both error and ObjectMarshaler, logged via .Err(err) to a buffer, asserting json.Valid(output) == true and that the object is nested as "error":{"code":500,"message":"boom"} (not "error":,).

Red-green verified in docker golang:latest:

  • Before fix: FAIL -- "error":,"code":500,..., json.Valid false.
  • After fix: PASS -- valid nested JSON.

Existing object/error suite (TestLoggerObject, TestLoggerObjects, TestLoggerErrorStack, TestFixMissingErrEntry) still passes; gofmt clean.

Note (follow-up, not in this PR)

Any() has the same latent bug in its case ObjectMarshaler: branch (logger.go ~L2319) -- it also appends "key": then calls MarshalObject directly. Worth a separate fix.


AI-assisted: this change was prepared with the help of an AI coding assistant and reviewed by me.

When an error passed to .Err()/.AnErr() also implements ObjectMarshaler, the
logger emitted invalid JSON. AnErr wrote the "error": key then called
o.MarshalObject(e) directly; each field method prepends a comma, so the buffer
became "error":,"code":500,... with a stray leading comma and the object's
fields leaking to the top level (json.Valid false).

Mirror the existing Object() convention: record n := len(e.buf) before
MarshalObject, then rewrite the stray leading comma at n to '{' and append '}'
(an empty marshaler yields null). The non-ObjectMarshaler string path is
unchanged.

Fixes phuslu#110
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ObjectMarshaler produces invalid JSON

1 participant