Skip to content

[BUG] InternalDaprError in actor method call can cause serialisation error when returning exception details #761

@Druid-of-Luhn

Description

@Druid-of-Luhn

Expected Behavior

When calling an actor method results in an InternalDaprError being raised, the exception details should be returned without any issue, whatever their content.

Actual Behavior

If the exception details, which are returned as a dict (with ex.as_dict()), contain bytes or any other non-JSON-serialisable value, then a JSON serialisation error is raised rather than returning the details of the initial exception.

Steps to Reproduce the Problem

  1. Have an actor method call fail due to an InternalDaprError.
  2. Have the exception contain a non-JSON-serialisable value (like bytes).
  3. The exception that is thrown is of a JSON serialisation error, rather than a 500 response containing the original exception details.

The issue is caused when line 99 in ext/dapr-ext-fastapi/dapr/ext/fastapi/actor.py is hit, resulting in line 47 trying to serialise a non-serialisable value to JSON (evidently a dict that at some level contains a bytes object).

Stack trace extract:

  File "venv\Lib\site-packages\fastapi\routing.py", line 212, in run_endpoint_function
    return await dependant.call(**values)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "venv\Lib\site-packages\dapr\ext\fastapi\actor.py", line 99, in actor_method
    return _wrap_response(status.HTTP_500_INTERNAL_SERVER_ERROR, ex.as_dict())
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "venv\Lib\site-packages\dapr\ext\fastapi\actor.py", line 47, in _wrap_response
    resp = JSONResponse(content=msg, status_code=status_code)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "venv\Lib\site-packages\starlette\responses.py", line 180, in __init__
    super().__init__(content, status_code, headers, media_type, background)
  File "venv\Lib\site-packages\starlette\responses.py", line 43, in __init__
    self.body = self.render(content)
                ^^^^^^^^^^^^^^^^^^^^
  File "venv\Lib\site-packages\starlette\responses.py", line 183, in render
    return json.dumps(
           ^^^^^^^^^^^
  File "AppData\Local\miniconda3\Lib\json\__init__.py", line 238, in dumps
    **kw).encode(obj)
          ^^^^^^^^^^^
  File "AppData\Local\miniconda3\Lib\json\encoder.py", line 200, in encode
    chunks = self.iterencode(o, _one_shot=True)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "AppData\Local\miniconda3\Lib\json\encoder.py", line 258, in iterencode
    return _iterencode(o, 0)
           ^^^^^^^^^^^^^^^^^
  File "AppData\Local\miniconda3\Lib\json\encoder.py", line 180, in default
    raise TypeError(f'Object of type {o.__class__.__name__} '
TypeError: Object of type bytes is not JSON serializable

Release Note

RELEASE NOTE: FIX Internal Dapr error during actor method call no longer raises a JSON serialisation error.

Metadata

Metadata

Assignees

No one assigned

    Labels

    kind/bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions