mirror of https://github.com/zulip/zulip.git
slack_incoming: Add ok=false to JSON in case of error.
Previously, errors were returned using Zulip's default format, which did not match Slack's expected response structure. This change ensures that errors in the Slack incoming webhook handler return JSON responses in Slack's expected format: {ok: false, error: "error string"}. Fixes: #31878.
This commit is contained in:
parent
46a0c6507c
commit
d448b75176
|
@ -66,7 +66,8 @@ Hello, world.
|
||||||
def test_message_without_payload(self) -> None:
|
def test_message_without_payload(self) -> None:
|
||||||
self.url = self.build_webhook_url()
|
self.url = self.build_webhook_url()
|
||||||
result = self.client_post(self.url)
|
result = self.client_post(self.url)
|
||||||
self.assert_json_error(result, "Missing 'payload' argument")
|
self.assertEqual(result.json()["error"], "Missing 'payload' argument")
|
||||||
|
self.assertEqual(result.json()["ok"], False)
|
||||||
|
|
||||||
def test_message_with_actions(self) -> None:
|
def test_message_with_actions(self) -> None:
|
||||||
expected_topic_name = "C1H9RESGL"
|
expected_topic_name = "C1H9RESGL"
|
||||||
|
|
|
@ -1,10 +1,13 @@
|
||||||
# Webhooks for external integrations.
|
# Webhooks for external integrations.
|
||||||
import re
|
import re
|
||||||
|
from collections.abc import Callable
|
||||||
|
from functools import wraps
|
||||||
from itertools import zip_longest
|
from itertools import zip_longest
|
||||||
from typing import Literal, TypedDict, cast
|
from typing import Literal, TypedDict, cast
|
||||||
|
|
||||||
from django.http import HttpRequest, HttpResponse
|
from django.http import HttpRequest, HttpResponse, JsonResponse
|
||||||
from django.utils.translation import gettext as _
|
from django.utils.translation import gettext as _
|
||||||
|
from typing_extensions import ParamSpec
|
||||||
|
|
||||||
from zerver.decorator import webhook_view
|
from zerver.decorator import webhook_view
|
||||||
from zerver.lib.exceptions import JsonableError
|
from zerver.lib.exceptions import JsonableError
|
||||||
|
@ -25,9 +28,31 @@ from zerver.lib.validator import (
|
||||||
from zerver.lib.webhooks.common import OptionalUserSpecifiedTopicStr, check_send_webhook_message
|
from zerver.lib.webhooks.common import OptionalUserSpecifiedTopicStr, check_send_webhook_message
|
||||||
from zerver.models import UserProfile
|
from zerver.models import UserProfile
|
||||||
|
|
||||||
|
ParamT = ParamSpec("ParamT")
|
||||||
|
|
||||||
|
|
||||||
|
def slack_error_handler(view_func: Callable[..., HttpResponse]) -> Callable[..., HttpResponse]:
|
||||||
|
"""
|
||||||
|
A decorator that catches JsonableError exceptions and returns a
|
||||||
|
Slack-compatible error response in the format:
|
||||||
|
{ok: false, error: "error message"}.
|
||||||
|
"""
|
||||||
|
|
||||||
|
@wraps(view_func)
|
||||||
|
def wrapped_view(
|
||||||
|
request: HttpRequest, *args: ParamT.args, **kwargs: ParamT.kwargs
|
||||||
|
) -> HttpResponse:
|
||||||
|
try:
|
||||||
|
return view_func(request, *args, **kwargs)
|
||||||
|
except JsonableError as error:
|
||||||
|
return JsonResponse({"ok": False, "error": error.msg}, status=error.http_status_code)
|
||||||
|
|
||||||
|
return wrapped_view
|
||||||
|
|
||||||
|
|
||||||
@webhook_view("SlackIncoming")
|
@webhook_view("SlackIncoming")
|
||||||
@typed_endpoint
|
@typed_endpoint
|
||||||
|
@slack_error_handler
|
||||||
def api_slack_incoming_webhook(
|
def api_slack_incoming_webhook(
|
||||||
request: HttpRequest,
|
request: HttpRequest,
|
||||||
user_profile: UserProfile,
|
user_profile: UserProfile,
|
||||||
|
|
Loading…
Reference in New Issue