-
-
Notifications
You must be signed in to change notification settings - Fork 4.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ref(sentry apps): Improve Errors for Alert Rule Creation for Sentry Apps #82067
base: master
Are you sure you want to change the base?
ref(sentry apps): Improve Errors for Alert Rule Creation for Sentry Apps #82067
Conversation
trigger_sentry_app_action_creators_for_incidents(serialized_data) | ||
except (SentryAppError, SentryAppIntegratorError) as e: | ||
return Response( | ||
str(e), |
Check warning
Code scanning / CodeQL
Information exposure through an exception Medium
Stack trace information
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix AI 27 days ago
To fix the problem, we need to ensure that detailed exception messages are not exposed to the end user. Instead, we should log the detailed error message on the server and return a generic error message to the user. This can be achieved by modifying the exception handling code to log the exception and return a generic error message.
- Modify the exception handling code in the
create_sentry_app_alert_rule_component_for_incidents
function to log the detailed error message and return a generic error message. - Modify the exception handling code in the
create_sentry_app_alert_rule_issues_component
function to log the detailed error message and return a generic error message.
-
Copy modified line R42 -
Copy modified line R44 -
Copy modified line R63 -
Copy modified line R65
@@ -41,4 +41,5 @@ | ||
except (SentryAppError, SentryAppIntegratorError) as e: | ||
sentry_sdk.capture_exception(e) | ||
return Response( | ||
str(e), | ||
"An error occurred while processing your request.", | ||
status=status.HTTP_400_BAD_REQUEST, | ||
@@ -61,4 +62,5 @@ | ||
except (SentryAppError, SentryAppIntegratorError) as e: | ||
sentry_sdk.capture_exception(e) | ||
return Response( | ||
{"actions": [str(e)]}, | ||
{"actions": ["An error occurred while processing your request."]}, | ||
status=status.HTTP_400_BAD_REQUEST, |
|
||
except (SentryAppError, SentryAppIntegratorError) as e: | ||
return Response( | ||
{"actions": [str(e)]}, |
Check warning
Code scanning / CodeQL
Information exposure through an exception Medium
Stack trace information
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix AI 27 days ago
To fix the problem, we need to ensure that detailed exception messages are not exposed to the user. Instead, we should log the detailed error message on the server and return a generic error message to the user. This can be achieved by modifying the exception handling code to log the exception and return a generic error message.
- Modify the exception handling block to log the detailed error message using
sentry_sdk.capture_exception(e)
. - Return a generic error message to the user.
-
Copy modified line R62 -
Copy modified line R64
@@ -61,4 +61,5 @@ | ||
except (SentryAppError, SentryAppIntegratorError) as e: | ||
sentry_sdk.capture_exception(e) | ||
return Response( | ||
{"actions": [str(e)]}, | ||
{"actions": ["An error occurred while processing the request."]}, | ||
status=status.HTTP_400_BAD_REQUEST, |
Codecov ReportAttention: Patch coverage is ✅ All tests successful. No failed tests found. Additional details and impacted files@@ Coverage Diff @@
## master #82067 +/- ##
===========================================
+ Coverage 52.94% 80.37% +27.42%
===========================================
Files 7247 7273 +26
Lines 319932 321339 +1407
Branches 20944 20944
===========================================
+ Hits 169397 258264 +88867
+ Misses 150133 62673 -87460
Partials 402 402 |
trigger_sentry_app_action_creators_for_incidents(serialized_data) | ||
except (SentryAppError, SentryAppIntegratorError) as e: | ||
return Response( | ||
str(e), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add a comment here for future engineers about why this is safe.
raise Exception(result.message) | ||
|
||
|
||
def create_sentry_app_alert_rule_component_for_incidents( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is confusing to me that one of the create component methods you have here returns a component and one of them return an error and None on success.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[1] I don't see much benefit in this method. How about you directly call trigger_sentry_app_action_creators_for_incidents
and let the exception go through.
@@ -285,7 +285,9 @@ def put(self, request: Request, project, rule) -> Response: | |||
context = {"uuid": client.uuid} | |||
return Response(context, status=202) | |||
|
|||
trigger_sentry_app_action_creators_for_issues(actions=kwargs["actions"]) | |||
result = create_sentry_app_alert_rule_issues_component(actions=kwargs["actions"]) | |||
if isinstance(result, Response): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's not good practice to have different typed returned from a method and then decide what to do with it based on type. I have a suggestion below on how to improve this. Please read the comments annotated with [n] in the order on n.
@@ -285,7 +285,9 @@ def put(self, request: Request, project, rule) -> Response: | |||
context = {"uuid": client.uuid} | |||
return Response(context, status=202) | |||
|
|||
trigger_sentry_app_action_creators_for_issues(actions=kwargs["actions"]) | |||
result = create_sentry_app_alert_rule_issues_component(actions=kwargs["actions"]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[2] Then wrap this in try catch and then in the catch, catch the exception and call a method like return IntegrationResponse.from_exception()
where this method is a util that does all the work you're doing to turn exceptions into response.
If from_exception() needs to know the caller for some reason to parse the errors better you can pass that as a param.
@@ -82,7 +84,12 @@ def update_alert_rule(request: Request, organization, alert_rule): | |||
partial=True, | |||
) | |||
if serializer.is_valid(): | |||
trigger_sentry_app_action_creators_for_incidents(serializer.validated_data) | |||
raised_error = create_sentry_app_alert_rule_component_for_incidents( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All comments applies to this method as well.
Introduces two classes to represent Sentry App exceptions:
SentryAppError should be used to represent client side errors like failed validation. For the webhook, these should not be sent to the integrator.
SentryAppIntegratorError is used to represent errors between Sentry & the integrator, i.e connection failed, integrator response is incorrect etc. These should be sent to the integrator for the webhook.
For this PR, we want to start wrapping errors in the SentryApp flows with these distinctions. And then in the endpoints we want to catch these two specific errors and return the error message. More info here in notion
This PR is a split of #81877 since that was turning into 2 PRs into 1
Context for Alert Rule Sentry App creation: Notion doc