fix: Propagate muted flag to :error telemetry events#174
Merged
crbelaus merged 1 commit intoelixir-error-tracker:mainfrom May 1, 2026
Merged
Conversation
`Repo.insert!(_, on_conflict: [set: [...]])` only round-trips the columns it sets, so the in-memory `Error` struct dispatched to subscribers of `[:error_tracker, :error, :new]` and `[:error_tracker, :error, :unresolved]` always carried the schema default (`muted: false`), regardless of the row's real state in the database. This made the dashboard mute action effectively a no-op for those two events. The DB row is already queried for `existing_status` and `muted` at the top of `upsert_error!/5`, so stamp the in-memory struct with that value before dispatching the telemetry events. Two-line change, no public API surface modified — subscribers that already read `metadata.error.muted` start working without any change on their side.
crbelaus
approved these changes
May 1, 2026
Contributor
crbelaus
left a comment
There was a problem hiding this comment.
This is looking great. Thanks for your contribution! 🙇
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Hi @crbelaus,
We're a team that has been using your library in production for a few months now, and we're very happy with it. Thank you very much for your work.
We ran into a situation where the mute action exposed in the dashboard wasn't being respected by our notifier. Our handler subscribes to
[:error_tracker, :error, :new]and[:error_tracker, :error, :unresolved]and inspectsmetadata.error.mutedbefore sending an alert, so muted errors should silently pass through. In practice it never did: every dispatched%Error{}struct carriedmuted: false, regardless of the row's real state in the DB, so errors that operators had explicitly silenced from the UI kept paging us.The
[:error_tracker, :occurrence, :new]event does expose a working:mutedmetadata key, but it isn't the right signal for our use case — we only want to react to genuinely new errors and to regressions (resolved → unresolved), not to every individual occurrence.After digging in we found that
upsert_error!/5already reads bothexisting_statusandmutedfrom the DB before the upsert, but it never stampsmutedonto the in-memory struct it hands toTelemetry.new_error/1/Telemetry.unresolved_error/1. BecauseRepo.insert!(_, on_conflict: [set: [...]])doesn't round-trip the columns it didn't set, the struct keeps the schema default (muted: false) even when the DB row is muted.We've been running a fork with this fix for a while and it's worked well for us. We wanted to offer it upstream in case you find the direction acceptable. We're happy to adjust the approach if you'd prefer a different shape or semantics — please consider this a humble proposal rather than a prescription.
Changes
Errorstruct with themutedvalue already fetched from the DB, right before dispatching the:newand:unresolvedtelemetry events.Errorschema already declaresmuted, so existing subscribers that readmetadata.error.mutedstart receiving the real value without any code change on their side.[:error_tracker, :occurrence, :new]event is untouched (it already exposes:mutedas a separate metadata key, and that path was working correctly).Why this shape, and not a separate metadata key
The
Errorschema already declaresmutedas a field, so the struct felt like the natural place for that information to live. Updating the struct keeps consistency with how the rest of the code treats%Error{}and avoids changing the metadata shape on existing subscribers. That said, if you'd rather expose:mutedas a separate metadata key on the:new/:unresolvedevents to mirror:occurrence, :new, we're happy to switch to that.Test plan
test/error_tracker/telemetry_test.exsthat mutes and resolves an error, triggers it again, and asserts the:unresolvedpayload reflectsmuted: true.main(the dispatched struct showsmuted: nil) and passes with the fix applied.--warnings-as-errors.Regards