-
Notifications
You must be signed in to change notification settings - Fork 131
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[BUG] InternalDaprError in actor method call can cause serialisation error when returning exception details #761
Comments
My temporary fix is to wrap the code that results in the data being serialised to JSON in a try/catch, and using def _wrap_response(
status_code: int,
msg: Any,
error_code: Optional[str] = None,
content_type: Optional[str] = DEFAULT_CONTENT_TYPE,
):
resp = None
if isinstance(msg, str):
response_obj = {
'message': msg,
}
if not (status_code >= 200 and status_code < 300) and error_code:
response_obj['errorCode'] = error_code
resp = JSONResponse(content=response_obj, status_code=status_code)
elif isinstance(msg, bytes):
resp = Response(content=msg, media_type=content_type)
else:
# BEGIN NEW CODE
try:
resp = JSONResponse(content=msg, status_code=status_code)
except Exception:
resp = _wrap_response(status_code, repr(msg), error_code, content_type)
# END NEW CODE
return resp However the actual error comes from the fact that a
class DaprInternalError(Exception):
"""DaprInternalError encapsulates all Dapr exceptions"""
def __init__(
self,
message: Optional[str],
error_code: Optional[str] = ERROR_CODE_UNKNOWN,
raw_response_bytes: Optional[bytes] = None,
):
self._message = message
self._error_code = error_code
self._raw_response_bytes = raw_response_bytes
def as_dict(self):
return {
'message': self._message,
'errorCode': self._error_code,
'raw_response_bytes': self._raw_response_bytes,
} |
Thanks for reporting this @Druid-of-Luhn . I was able to reproduce the problem and I think it would be best if we added something like this in the def json_safe_dict(self):
error_dict = {'message': self._message, 'errorCode': self._error_code, }
if self._raw_response_bytes is not None:
# Encode bytes to base64 for JSON compatibility
error_dict['raw_response_bytes'] = base64.b64encode(self._raw_response_bytes).decode(
'utf-8')
return error_dict And then in actor.py:
Would you like to send a PR with these changes and maybe an extra test for them? |
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
InternalDaprError
.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 abytes
object).Stack trace extract:
Release Note
RELEASE NOTE: FIX Internal Dapr error during actor method call no longer raises a JSON serialisation error.
The text was updated successfully, but these errors were encountered: