Skip to content

Commit

Permalink
chore(snetry apps): Make SentryAppSentryErrors for Sentry side errors (
Browse files Browse the repository at this point in the history
  • Loading branch information
Christinarlong authored Jan 8, 2025
1 parent b381b21 commit 62bcff6
Show file tree
Hide file tree
Showing 6 changed files with 42 additions and 23 deletions.
16 changes: 14 additions & 2 deletions src/sentry/sentry_apps/api/bases/sentryapps.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from functools import wraps
from typing import Any

import sentry_sdk
from rest_framework.exceptions import PermissionDenied
from rest_framework.permissions import BasePermission
from rest_framework.request import Request
Expand All @@ -26,7 +27,11 @@
)
from sentry.sentry_apps.models.sentry_app import SentryApp
from sentry.sentry_apps.services.app import RpcSentryApp, app_service
from sentry.sentry_apps.utils.errors import SentryAppError, SentryAppIntegratorError
from sentry.sentry_apps.utils.errors import (
SentryAppError,
SentryAppIntegratorError,
SentryAppSentryError,
)
from sentry.users.models.user import User
from sentry.users.services.user import RpcUser
from sentry.users.services.user.service import user_service
Expand Down Expand Up @@ -125,12 +130,19 @@ def handle_exception_with_details(self, request, exc, handler_context=None, scop
) or super().handle_exception_with_details(request, exc, handler_context, scope)

def _handle_sentry_app_exception(self, exception: Exception):
# If the error_type attr exists we know the error is one of SentryAppError or SentryAppIntegratorError
if isinstance(exception, SentryAppIntegratorError) or isinstance(exception, SentryAppError):
response = Response({"detail": str(exception)}, status=exception.status_code)
response.exception = True
return response

elif isinstance(exception, SentryAppSentryError):
error_id = sentry_sdk.capture_exception(exception)
return Response(
{
"detail": f"An issue occured during the integration platform process. Sentry error ID: {error_id}"
},
status=500,
)
# If not an audited sentry app error then default to using default error handler
return None

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
from rest_framework import serializers
from rest_framework.request import Request
from rest_framework.response import Response
from sentry_sdk import capture_exception

from sentry.api.api_owners import ApiOwner
from sentry.api.api_publish_status import ApiPublishStatus
Expand Down Expand Up @@ -45,22 +44,14 @@ def post(self, request: Request, installation) -> Response:

serializer = PlatformExternalIssueSerializer(data=request.data)
if serializer.is_valid():
try:
external_issue = ExternalIssueCreator(
install=installation,
group=group,
web_url=data["webUrl"],
project=data["project"],
identifier=data["identifier"],
).run()
except Exception as e:
error_id = capture_exception(e)
return Response(
{
"error": f"An issue occured while trying to create external issue. Sentry error ID: {error_id}"
},
status=500,
)
external_issue = ExternalIssueCreator(
install=installation,
group=group,
web_url=data["webUrl"],
project=data["project"],
identifier=data["identifier"],
).run()

return Response(
serialize(
objects=external_issue, serializer=ResponsePlatformExternalIssueSerializer()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
from sentry.models.group import Group
from sentry.sentry_apps.models.platformexternalissue import PlatformExternalIssue
from sentry.sentry_apps.services.app import RpcSentryAppInstallation
from sentry.sentry_apps.utils.errors import SentryAppSentryError

logger = logging.getLogger("sentry.sentry_apps.external_issues")

Expand Down Expand Up @@ -45,4 +46,4 @@ def run(self) -> PlatformExternalIssue:
"sentry_app_slug": self.install.sentry_app.slug,
},
)
raise
raise SentryAppSentryError(e) from e
3 changes: 2 additions & 1 deletion src/sentry/sentry_apps/external_issues/issue_link_creator.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
from sentry.sentry_apps.external_requests.issue_link_requester import IssueLinkRequester
from sentry.sentry_apps.models.platformexternalissue import PlatformExternalIssue
from sentry.sentry_apps.services.app import RpcSentryAppInstallation
from sentry.sentry_apps.utils.errors import SentryAppSentryError
from sentry.users.services.user import RpcUser

VALID_ACTIONS = ["link", "create"]
Expand All @@ -32,7 +33,7 @@ def run(self) -> PlatformExternalIssue:

def _verify_action(self) -> None:
if self.action not in VALID_ACTIONS:
raise APIUnauthorized(f"Invalid action '{self.action}'")
raise SentryAppSentryError(APIUnauthorized(f"Invalid action '{self.action}'"))

def _make_external_request(self) -> dict[str, Any]:
response = IssueLinkRequester(
Expand Down
14 changes: 14 additions & 0 deletions src/sentry/sentry_apps/utils/errors.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,17 @@ def __init__(
) -> None:
if status_code:
self.status_code = status_code


# Represents an error that's our (sentry's) fault
class SentryAppSentryError(Exception):
error_type = SentryAppErrorType.SENTRY
status_code = 500

def __init__(
self,
error: Exception | None = None,
status_code: int | None = None,
) -> None:
if status_code:
self.status_code = status_code
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import pytest
import responses

from sentry.coreapi import APIUnauthorized
from sentry.sentry_apps.external_issues.issue_link_creator import IssueLinkCreator
from sentry.sentry_apps.models.platformexternalissue import PlatformExternalIssue
from sentry.sentry_apps.services.app import app_service
from sentry.sentry_apps.utils.errors import SentryAppSentryError
from sentry.testutils.cases import TestCase
from sentry.users.services.user.serial import serialize_rpc_user

Expand Down Expand Up @@ -60,7 +60,7 @@ def test_creates_external_issue(self):
assert external_issue.display_name == "Projectname#issue-1"

def test_invalid_action(self):
with pytest.raises(APIUnauthorized):
with pytest.raises(SentryAppSentryError):
IssueLinkCreator(
install=self.install,
group=self.group,
Expand Down

0 comments on commit 62bcff6

Please sign in to comment.