Skip to content

Conversation

@xgoffin
Copy link
Contributor

@xgoffin xgoffin commented Nov 27, 2025

What does this PR do?

  • Sentry Reporter now has an array of funcs to check reported errors and build the level on Sentry based on these
  • Callers may create a Reporter with custom error checking funcs by adding to them or overwriting them

Fixes #

What are the observable changes?

Good PR checklist

  • Title makes sense
  • Is against the correct branch
  • Only addresses one issue
  • Properly assigned
  • Added/updated tests
  • Added/updated documentation
  • Properly labeled

Additional Notes


Note

Adds configurable error-level mapping to Sentry events and updates reporter behavior accordingly.

  • Introduces ErrorLevelMapper and helpers (ErrorIsLevel, ErrorIsOfTypeLevel[T], ErrorCauseTextContainsLevel) with defaultErrorLevelMappers mapping common transient errors (e.g., context.DeadlineExceeded, io.EOF, TLS handshake timeouts) to warning
  • Extends Options with ErrorLevelMappers and new option funcs: AppendErrorLevelMappers and ReplaceErrorLevelMappers
  • Replaces defaultOptions var with defaultOptions() and wires levelMappers into Reporter
  • buildEvent now sets evt.Level via computeLevel(err) (defaults to error when no mapper matches)
  • Adds tests covering sentinel, wrapped, text-matched, and type-based mappings

Written by Cursor Bugbot for commit c51e6c2. This will update automatically on new commits. Configure here.


var (
defaultErrorLevelFuncs = []ErrorLevelFunc{
ErrorIsFunc(context.DeadlineExceeded, sentry.LevelWarning),

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Won't this hide some big errors ? Like deadlock or things like that ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thankfully this doesn't hide them, simply marks them as severity "Warning", which will allow us to have 2 different boards (one for errors, one for warnings), which ought to filter a lot of the noise.
We'll still notice if we have 3000 warnings rise up all of a sudden 👀

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah ok nice :)

Copy link

@lordteka lordteka left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice improvment, also nice effort on the doc/comment

}
}

// ErrorCauseTextContainsFunc an ErrorLevelFunc of the passed level that checks

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

missing a word here

Copy link

@karitham karitham left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚀

}

// AppendErrorLevelFuncs adds the passed funcs to the ErrorLevelFuncs of the Reporter
func AppendErrorLevelFuncs(funcs []ErrorLevelFunc) Option {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
func AppendErrorLevelFuncs(funcs []ErrorLevelFunc) Option {
func AppendErrorLevelFuncs(funcs ...ErrorLevelFunc) Option {

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

clever man

Copy link

@karitham karitham Nov 27, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

UX improvements through the roof.

You can do the replace one as well but I think that one is less important, and it makes sense there to pass nil to remove any filtering, wheras ReplaceErrorLevelFuncs() isn't really self-descriptive

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeap, and I feel like it expects a "whole" array for replacement rather than a variadic
It most likely also won't be used much 😄

Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This PR is being reviewed by Cursor Bugbot

Details

Your team is on the Bugbot Free tier. On this plan, Bugbot will review limited PRs each billing cycle for each member of your team.

To receive Bugbot reviews on all of your PRs, visit the Cursor dashboard to activate Pro and start your 14-day free trial.

}

return ""
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nil error causes panic in ErrorCauseTextContainsLevel mapper

The ErrorCauseTextContainsLevel function doesn't handle nil errors gracefully. Calling base.UnwrapAll(nil).Error() will panic because UnwrapAll(nil) returns nil, and invoking .Error() on a nil error interface causes a nil pointer dereference. This is inconsistent with ErrorIsLevel and ErrorIsOfTypeLevel, which both handle nil errors safely (via uerrors.Is and uerrors.IsOfType). While current usage is protected by the nil check in buildEvent, this public API function could panic if used directly with a nil error.

Fix in Cursor Fix in Web

stringPrefix(reporter.HTTPRequestHeaderKeyPrefix),
stringPrefix(reporter.HTTPRequestQueryValuesKeyPrefix),
},
type ErrorLevelMapper func(error) sentry.Level
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I saw that you applied the comment https://github.com/upfluence/errors/pull/18/changes#r2578258351 in the reporter.go file can you apply the comment in this file as well

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, for exported names, we had that conversation previously with @Sypheos and @karitham : #18 (comment), not sure it's a very good idea for clarity's sake to just call them LevelFuncs, for instance, unless you have a better idea?

For private constructions I don't mind

@xgoffin xgoffin merged commit 7f7646a into master Dec 30, 2025
6 checks passed
@xgoffin xgoffin deleted the xg/errorlevel branch December 30, 2025 12:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants