Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/sentry/utils/sentry_apps/webhooks.py
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,8 @@ def send_and_save_webhook_request(
org_id = app_platform_event.install.organization_id
slug = sentry_app.slug_for_metrics
url = url or sentry_app.webhook_url
if not url:
return Response()
Comment on lines +257 to +258

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Bug: The early return for an empty webhook_url incorrectly logs a configuration error as a SUCCESS in metrics because lifecycle.record_halt() is not called before exiting.
Severity: MEDIUM

Suggested Fix

Before the return Response() statement for an empty url, add a call to lifecycle.record_halt() to ensure the event lifecycle correctly records the interaction as halted due to a configuration issue, rather than incorrectly logging it as a success.

Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent. Verify if this is a real issue. If it is, propose a fix; if not, explain why it's
not valid.

Location: src/sentry/utils/sentry_apps/webhooks.py#L257-L258

Potential issue: When a `SentryApp` has an empty `webhook_url`, the function returns
early. This happens inside a `SentryAppInteractionEvent.capture()` context manager which
defaults to `assume_success=True`. Because the function exits cleanly without an
explicit call to `lifecycle.record_halt()`, the event is incorrectly recorded as a
`SUCCESS` in metrics. This corrupts SLO tracking by treating a configuration failure as
a successful interaction, making it harder to detect misconfigured webhooks.

Did we get this right? 👍 / 👎 to inform future reviews.

lifecycle.add_extras(
{
"org_id": org_id,
Expand All @@ -264,7 +266,6 @@ def send_and_save_webhook_request(
}
)

assert url is not None
custom_headers_enabled = False
try:
owner_context = organization_service.get_organization_by_id(
Expand Down
Loading