Skip to content

Commit bdbcfeb

Browse files
chore(jira): Add halts for the weird jira html errors (#102370)
1 parent 20b3bcf commit bdbcfeb

File tree

4 files changed

+77
-0
lines changed

4 files changed

+77
-0
lines changed

src/sentry/integrations/jira/integration.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@
5050
IntegrationConfigurationError,
5151
IntegrationError,
5252
IntegrationFormError,
53+
IntegrationProviderError,
5354
)
5455
from sentry.silo.base import all_silo_function
5556
from sentry.users.models.identity import Identity
@@ -1008,6 +1009,12 @@ def raise_error(self, exc: Exception, identity: Identity | None = None) -> NoRet
10081009
},
10091010
)
10101011
raise IntegrationConfigurationError(exc.text) from exc
1012+
elif isinstance(exc, ApiError):
1013+
if "Product Unavailable" in exc.text or "Page Unavailable" in exc.text:
1014+
raise IntegrationProviderError(
1015+
"Something went wrong while communicating with Jira"
1016+
) from exc
1017+
10111018
super().raise_error(exc, identity=identity)
10121019

10131020
def sync_assignee_outbound(

src/sentry/issues/endpoints/group_integration_details.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
IntegrationConfigurationError,
3232
IntegrationError,
3333
IntegrationFormError,
34+
IntegrationProviderError,
3435
)
3536
from sentry.signals import integration_issue_created, integration_issue_linked
3637
from sentry.types.activity import ActivityType
@@ -319,6 +320,14 @@ def post(self, request: Request, group, integration_id) -> Response:
319320
except IntegrationError as e:
320321
lifecycle.record_failure(e)
321322
return Response({"non_field_errors": [str(e)]}, status=400)
323+
except IntegrationProviderError as exc:
324+
lifecycle.record_halt(exc)
325+
return Response(
326+
{
327+
"detail": f"Something went wrong while communicating with {integration.provider}"
328+
},
329+
status=503,
330+
)
322331

323332
external_issue_key = installation.make_external_key(data)
324333
external_issue, created = ExternalIssue.objects.get_or_create(

src/sentry/rules/actions/integrations/create_ticket/utils.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
ApiUnauthorized,
2525
IntegrationConfigurationError,
2626
IntegrationFormError,
27+
IntegrationProviderError,
2728
IntegrationResourceNotFoundError,
2829
)
2930
from sentry.silo.base import region_silo_function
@@ -185,6 +186,7 @@ def create_issue(event: GroupEvent, futures: Sequence[RuleFuture]) -> None:
185186
InvalidIdentity,
186187
ApiUnauthorized,
187188
IntegrationResourceNotFoundError,
189+
IntegrationProviderError,
188190
) as e:
189191
# Most of the time, these aren't explicit failures, they're
190192
# some misconfiguration of an issue field - typically Jira.

tests/sentry/integrations/jira/test_integration.py

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
IntegrationConfigurationError,
2424
IntegrationError,
2525
IntegrationFormError,
26+
IntegrationProviderError,
2627
)
2728
from sentry.silo.base import SiloMode
2829
from sentry.testutils.cases import APITestCase, IntegrationTestCase
@@ -778,6 +779,64 @@ def test_create_issue_with_configuration_error(self) -> None:
778779
}
779780
)
780781

782+
@responses.activate
783+
def test_create_issue_product_unavailable_error(self) -> None:
784+
responses.add(
785+
responses.GET,
786+
"https://example.atlassian.net/rest/api/2/issue/createmeta",
787+
body=StubService.get_stub_json("jira", "createmeta_response.json"),
788+
content_type="json",
789+
)
790+
# Simulate Jira returning an HTML "Product Unavailable" error page
791+
responses.add(
792+
responses.POST,
793+
"https://example.atlassian.net/rest/api/2/issue",
794+
status=503,
795+
body='<!DOCTYPE html>\n<html lang="en">\n <head>\n <title>Atlassian Cloud Notifications - Product Unavailable</title>\n </head>\n <body>\n <h1>Jira has been deactivated</h1>\n </body>\n</html>',
796+
content_type="text/html",
797+
)
798+
installation = self.integration.get_installation(self.organization.id)
799+
with pytest.raises(
800+
IntegrationProviderError, match="Something went wrong while communicating with Jira"
801+
):
802+
installation.create_issue(
803+
{
804+
"title": "example summary",
805+
"description": "example bug report",
806+
"issuetype": "1",
807+
"project": "10000",
808+
}
809+
)
810+
811+
@responses.activate
812+
def test_create_issue_page_unavailable_error(self) -> None:
813+
responses.add(
814+
responses.GET,
815+
"https://example.atlassian.net/rest/api/2/issue/createmeta",
816+
body=StubService.get_stub_json("jira", "createmeta_response.json"),
817+
content_type="json",
818+
)
819+
# Simulate Jira returning an HTML "Page Unavailable" error
820+
responses.add(
821+
responses.POST,
822+
"https://example.atlassian.net/rest/api/2/issue",
823+
status=503,
824+
body='<!DOCTYPE html>\n<html lang="en">\n <head>\n <title>Page Unavailable</title>\n </head>\n <body>\n <h1>Page Unavailable</h1>\n </body>\n</html>',
825+
content_type="text/html",
826+
)
827+
installation = self.integration.get_installation(self.organization.id)
828+
with pytest.raises(
829+
IntegrationProviderError, match="Something went wrong while communicating with Jira"
830+
):
831+
installation.create_issue(
832+
{
833+
"title": "example summary",
834+
"description": "example bug report",
835+
"issuetype": "1",
836+
"project": "10000",
837+
}
838+
)
839+
781840
@responses.activate
782841
def test_create_issue_labels_and_option(self) -> None:
783842
installation = self.integration.get_installation(self.organization.id)

0 commit comments

Comments
 (0)