Skip to content

fix(logging): bump sirupsen/logrus to v1.10.0, fix nil-Stringer crash it exposes - #4456

Closed
reinkrul wants to merge 3 commits into
masterfrom
chore/logrus-1.10-nil-safe-logging
Closed

fix(logging): bump sirupsen/logrus to v1.10.0, fix nil-Stringer crash it exposes#4456
reinkrul wants to merge 3 commits into
masterfrom
chore/logrus-1.10-nil-safe-logging

Conversation

@reinkrul

Copy link
Copy Markdown
Member

What

Bumps github.com/sirupsen/logrus v1.9.4 → v1.10.0 (held back from #4454 pending this fix) and fixes a crash it exposes.

Why

v1.10.0's rewritten TextFormatter.appendValue calls fmt.Stringer.String() directly instead of going through fmt.Sprint (which used to recover panics from it). Several places log a VC/VP's *ssi.URI ID via WithField, and that ID is nil whenever the credential/presentation has no id — optional per the VC/VP data model. URI.String() has a value receiver, so calling it through a nil *URI panics on dereference. Under v1.9.4 that produced a garbled log line; under v1.10.0 it crashes the process.

Confirmed by two tests that panicked under v1.10.0 alone: Test_wallet_HandleCredentialOffer and Test_networkPublisher_PublishCredential.

How

Adds core.SafeStringer[T comparable & fmt.Stringer], a small generic helper that returns nil for a nil pointer (which logs as "<nil>") instead of the value, so WithField never calls String() on one. Constraining T to comparable (true for any pointer type) lets it check for nil with a plain == comparison against the zero value — no reflection needed.

Applied at every call site found logging a VC/VP ID this way:

  • vcr/holder/openid.go, vcr/holder/sql_wallet.go
  • vcr/issuer/network_publisher.go, vcr/issuer/openid.go
  • vcr/search.go, vcr/store.go
  • vcr/revocation/statuslist2021_verifier.go
  • didman/didman.go
  • discovery/client.go

Out of scope

A few other spots (vcr/issuer/issuer.go) call .String() directly on a VC ID rather than passing the pointer to WithField. Those would already panic on a nil ID today, independent of this logrus bump (not a new regression), so left untouched here to keep this PR to the fix at hand.

… it exposes

v1.10.0's rewritten TextFormatter.appendValue calls fmt.Stringer.String()
directly instead of going through fmt.Sprint (which used to recover panics
from it). Several places log a VC/VP's *ssi.URI ID via WithField, which is
nil whenever the credential/presentation has no id (optional per the VC/VP
data model). URI.String() has a value receiver, so calling it through a nil
*URI panics on dereference: under v1.9.4 that produced a garbled log line,
under v1.10.0 it crashes the process.

Adds core.SafeStringer[T comparable & fmt.Stringer], a small generic helper
that returns nil for a nil pointer (logged as "<nil>") instead of the value,
so WithField never calls String() on one. Comparability lets it check for
nil without reflection. Applied at every call site found logging a VC/VP ID
this way: vcr/holder/openid.go, vcr/holder/sql_wallet.go,
vcr/issuer/network_publisher.go, vcr/issuer/openid.go, vcr/search.go,
vcr/store.go, vcr/revocation/statuslist2021_verifier.go, didman/didman.go,
discovery/client.go.

Confirmed by two tests that previously panicked under v1.10.0:
Test_wallet_HandleCredentialOffer and Test_networkPublisher_PublishCredential.
@qltysh

qltysh Bot commented Aug 19, 2026

Copy link
Copy Markdown
Contributor

1 new issue

Tool Category Rule Count
qlty Structure Function with many returns (count = 8): updateService 1

Not a fix for an existing bug: the crash only exists because of the logrus
v1.10.0 bump this same PR makes, so there's nothing here for a release-note
reader to act on.
@qltysh

qltysh Bot commented Aug 19, 2026

Copy link
Copy Markdown
Contributor

Qlty


Coverage Impact

This PR will not change total coverage.

Modified Files with Diff Coverage (10)

RatingFile% DiffUncovered Line #s
Coverage rating: B Coverage rating: B
vcr/search.go100.0%
Coverage rating: A Coverage rating: A
didman/didman.go100.0%
Coverage rating: A Coverage rating: A
vcr/store.go100.0%
Coverage rating: B Coverage rating: B
vcr/issuer/openid.go100.0%
Coverage rating: B Coverage rating: B
vcr/holder/sql_wallet.go100.0%
Coverage rating: A Coverage rating: A
vcr/holder/openid.go100.0%
Coverage rating: B Coverage rating: B
discovery/client.go100.0%
Coverage rating: A Coverage rating: A
vcr/issuer/network_publisher.go100.0%
Coverage rating: A Coverage rating: A
vcr/revocation/statuslist2021_verifier.go100.0%
New Coverage rating: A
core/logging.go100.0%
Total100.0%
🚦 See full report on Qlty Cloud »

🛟 Help
  • Diff Coverage: Coverage for added or modified lines of code (excludes deleted files). Learn more.

  • Total Coverage: Coverage for the whole repository, calculated as the sum of all File Coverage. Learn more.

  • File Coverage: Covered Lines divided by Covered Lines plus Missed Lines. (Excludes non-executable lines including blank lines and comments.)

    • Indirect Changes: Changes to File Coverage for files that were not modified in this PR. Learn more.

@reinkrul reinkrul closed this Sep 1, 2026
@reinkrul
reinkrul deleted the chore/logrus-1.10-nil-safe-logging branch September 1, 2026 07:37
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.

1 participant