from dataclasses import dataclass
from blacksheep import Application, pretty_json
app = Application()
@dataclass
class Access:
id: int
name: str
permissions: list[str]
@app.router.post("/")
def set_access(data: list[Access]):
# Just an example...
return pretty_json(data)
if __name__ == "__main__":
import uvicorn
uvicorn.run(app, port=44555, lifespan="on")
The server endpoint expects a list of objects. If the client sends a dictionary, the server produces a cryptic error message.
curl -X POST http://127.0.0.1:44555 -H "Content-Type: application/json" -d '{"id": 1, "name": "foo", "permissions": []}'
Bad Request: invalid parameter in request payload, caused by type Access or one of its subproperties. Error: __main__.Access() argument after ** must be a mapping, not str
"Bad Request: invalid parameter in request payload, caused by type Access or one of its subproperties. Error: main.Access() argument after ** must be a mapping, not str".
This happens because the function _get_default_converter_for_iterable does not handle properly this case.
Improve to raise a clearer exception:
def _get_default_converter_for_iterable(self, expected_type):
generic_type = self.get_type_for_generic_iterable(expected_type)
item_type = self.generic_iterable_annotation_item_type(expected_type)
if isinstance(item_type, ForwardRef): # pragma: no cover
from blacksheep.server.normalization import (
UnsupportedForwardRefInSignatureError,
)
raise UnsupportedForwardRefInSignatureError(expected_type)
item_converter = self._get_default_converter_single(item_type)
def list_converter(values):
if not isinstance(values, list):
raise BadRequest("Invalid input: expected a list of objects.")
return generic_type(item_converter(value) for value in values)
return list_converter
Consider the following example:
The server endpoint expects a list of objects. If the client sends a dictionary, the server produces a cryptic error message.
"Bad Request: invalid parameter in request payload, caused by type Access or one of its subproperties. Error: main.Access() argument after ** must be a mapping, not str".
This happens because the function
_get_default_converter_for_iterable
does not handle properly this case.Improve to raise a clearer exception: