Skip to content

Commit

Permalink
Merge pull request #844 from RasaHQ/handle-action-exceptions
Browse files Browse the repository at this point in the history
created catch all for exceptions to handle them properly
  • Loading branch information
tmbo authored Aug 30, 2022
2 parents c759c84 + 0039926 commit 692e0d2
Show file tree
Hide file tree
Showing 5 changed files with 60 additions and 10 deletions.
1 change: 1 addition & 0 deletions changelog/836.improvement.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Return a json response when encountering action execution exceptions. Log exceptions using logger rather than sanic default print.
30 changes: 21 additions & 9 deletions docs/static/spec/action-server.yml
Original file line number Diff line number Diff line change
Expand Up @@ -77,18 +77,30 @@ paths:
500:
description: >-
The action server encountered an exception while running the action.
content:
application/json:
schema:
type: object
properties:
request_body:
type: object
description: >-
Json body of the incoming request that resulted in the error.
error:
type: string
description: The error message.
components:
schemas:
Response:
allOf:
- $ref: '#/components/schemas/TextResponse'
- $ref: '#/components/schemas/ButtonResponse'
- $ref: '#/components/schemas/ElementResponse'
- $ref: '#/components/schemas/CustomResponse'
- $ref: '#/components/schemas/ImageResponse'
- $ref: '#/components/schemas/AttachmentResponse'
- $ref: '#/components/schemas/TemplateResponse'
- $ref: '#/components/schemas/ResponseResponse'
- $ref: "#/components/schemas/TextResponse"
- $ref: "#/components/schemas/ButtonResponse"
- $ref: "#/components/schemas/ElementResponse"
- $ref: "#/components/schemas/CustomResponse"
- $ref: "#/components/schemas/ImageResponse"
- $ref: "#/components/schemas/AttachmentResponse"
- $ref: "#/components/schemas/TemplateResponse"
- $ref: "#/components/schemas/ResponseResponse"

TextResponse:
description: Text which the bot should utter.
Expand Down Expand Up @@ -126,7 +138,7 @@ components:
buttons:
type: array
items:
$ref: '#/components/schemas/Button'
$ref: "#/components/schemas/Button"
ElementResponse:
description: Custom elements which should be sent to the user.
type: object
Expand Down
9 changes: 9 additions & 0 deletions rasa_sdk/endpoint.py
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,15 @@ async def actions(_) -> HTTPResponse:
body = [{"name": k} for k in executor.actions.keys()]
return response.json(body, status=200)

@app.exception(Exception)
async def exception_handler(request, exception: Exception):
logger.error(
msg=f"Exception occurred during execution of request {request}",
exc_info=exception,
)
body = {"error": str(exception), "request_body": request.json}
return response.json(body, status=500)

return app


Expand Down
13 changes: 13 additions & 0 deletions tests/test_actions.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,16 @@ def run(
domain: DomainDict,
) -> List[Dict[Text, Any]]:
return [SlotSet("test", "bar")]


class CustomActionRaisingException(Action):
def name(cls) -> Text:
return "custom_action_exception"

def run(
self,
dispatcher: CollectingDispatcher,
tracker: Tracker,
domain: DomainDict,
) -> List[Dict[Text, Any]]:
raise Exception("test exception")
17 changes: 16 additions & 1 deletion tests/test_endpoint.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@
# noinspection PyTypeChecker
app = ep.create_app(None)

import logging

logger = logging.getLogger(__name__)


def test_endpoint_exit_for_unknown_actions_package():
with pytest.raises(SystemExit):
Expand All @@ -22,7 +26,7 @@ def test_server_health_returns_200():
def test_server_list_actions_returns_200():
request, response = app.test_client.get("/actions")
assert response.status == 200
assert len(response.json) == 2
assert len(response.json) == 3


def test_server_webhook_unknown_action_returns_404():
Expand All @@ -34,6 +38,17 @@ def test_server_webhook_unknown_action_returns_404():
assert response.status == 404


def test_server_webhook_handles_action_exception():
data = {
"next_action": "custom_action_exception",
"tracker": {"sender_id": "1", "conversation_id": "default"},
}
request, response = app.test_client.post("/webhook", data=json.dumps(data))
assert response.status == 500
assert response.json.get("error") == "test exception"
assert response.json.get("request_body") == data


def test_server_webhook_custom_action_returns_200():
data = {
"next_action": "custom_action",
Expand Down

0 comments on commit 692e0d2

Please sign in to comment.