]> git.ipfire.org Git - thirdparty/fastapi/fastapi.git/commitdiff
🐛 Fix body validation error response, remove variable name when it is not embedded...
authorAndrew <amacfie@sent.com>
Sun, 14 Jun 2020 16:07:39 +0000 (12:07 -0400)
committerGitHub <noreply@github.com>
Sun, 14 Jun 2020 16:07:39 +0000 (18:07 +0200)
docs/en/docs/tutorial/handling-errors.md
fastapi/dependencies/utils.py
tests/test_multi_body_errors.py
tests/test_tutorial/test_body/test_tutorial001.py
tests/test_tutorial/test_body_nested_models/test_tutorial009.py
tests/test_tutorial/test_custom_request_and_route/test_tutorial002.py
tests/test_tutorial/test_handling_errors/test_tutorial005.py

index 19a6c568491fb4dcae2d172e35860f9eb101d931..c5d36702ce50d493eee64b775d30df6fe26745db 100644 (file)
@@ -215,7 +215,6 @@ You will receive a response telling you that the data is invalid containing the
     {
       "loc": [
         "body",
-        "item",
         "size"
       ],
       "msg": "value is not a valid integer",
index e7896f4910b580174e177c48ee187c10b3147853..003fa7f4ab179ed8778d4178493b3beabb34c2b0 100644 (file)
@@ -642,9 +642,17 @@ async def request_body_to_args(
         field = required_params[0]
         field_info = get_field_info(field)
         embed = getattr(field_info, "embed", None)
-        if len(required_params) == 1 and not embed:
+        field_alias_omitted = len(required_params) == 1 and not embed
+        if field_alias_omitted:
             received_body = {field.alias: received_body}
+
         for field in required_params:
+            loc: Tuple[str, ...]
+            if field_alias_omitted:
+                loc = ("body",)
+            else:
+                loc = ("body", field.alias)
+
             value: Any = None
             if received_body is not None:
                 if (
@@ -655,7 +663,7 @@ async def request_body_to_args(
                     try:
                         value = received_body.get(field.alias)
                     except AttributeError:
-                        errors.append(get_missing_field_error(field.alias))
+                        errors.append(get_missing_field_error(loc))
                         continue
             if (
                 value is None
@@ -667,7 +675,7 @@ async def request_body_to_args(
                 )
             ):
                 if field.required:
-                    errors.append(get_missing_field_error(field.alias))
+                    errors.append(get_missing_field_error(loc))
                 else:
                     values[field.name] = deepcopy(field.default)
                 continue
@@ -686,7 +694,9 @@ async def request_body_to_args(
                 awaitables = [sub_value.read() for sub_value in value]
                 contents = await asyncio.gather(*awaitables)
                 value = sequence_shape_to_type[field.shape](contents)
-            v_, errors_ = field.validate(value, values, loc=("body", field.alias))
+
+            v_, errors_ = field.validate(value, values, loc=loc)
+
             if isinstance(errors_, ErrorWrapper):
                 errors.append(errors_)
             elif isinstance(errors_, list):
@@ -696,12 +706,12 @@ async def request_body_to_args(
     return values, errors
 
 
-def get_missing_field_error(field_alias: str) -> ErrorWrapper:
+def get_missing_field_error(loc: Tuple[str, ...]) -> ErrorWrapper:
     if PYDANTIC_1:
-        missing_field_error = ErrorWrapper(MissingError(), loc=("body", field_alias))
+        missing_field_error = ErrorWrapper(MissingError(), loc=loc)
     else:  # pragma: no cover
         missing_field_error = ErrorWrapper(  # type: ignore
-            MissingError(), loc=("body", field_alias), config=BaseConfig,
+            MissingError(), loc=loc, config=BaseConfig,
         )
     return missing_field_error
 
index f198042619537d48e26ead11af35f50e47529c76..4719f0b27f3a3161c35d14dd03e0face72daa1fd 100644 (file)
@@ -104,7 +104,7 @@ single_error = {
     "detail": [
         {
             "ctx": {"limit_value": 0.0},
-            "loc": ["body", "item", 0, "age"],
+            "loc": ["body", 0, "age"],
             "msg": "ensure this value is greater than 0",
             "type": "value_error.number.not_gt",
         }
@@ -114,22 +114,22 @@ single_error = {
 multiple_errors = {
     "detail": [
         {
-            "loc": ["body", "item", 0, "name"],
+            "loc": ["body", 0, "name"],
             "msg": "field required",
             "type": "value_error.missing",
         },
         {
-            "loc": ["body", "item", 0, "age"],
+            "loc": ["body", 0, "age"],
             "msg": "value is not a valid decimal",
             "type": "type_error.decimal",
         },
         {
-            "loc": ["body", "item", 1, "name"],
+            "loc": ["body", 1, "name"],
             "msg": "field required",
             "type": "value_error.missing",
         },
         {
-            "loc": ["body", "item", 1, "age"],
+            "loc": ["body", 1, "age"],
             "msg": "value is not a valid decimal",
             "type": "type_error.decimal",
         },
index 806e712dc31085fa924422152d15fe0f075ef91d..df28a5d35d78ae8023e8fc323d2773b4ee229aee 100644 (file)
@@ -94,7 +94,7 @@ def test_openapi_schema():
 price_missing = {
     "detail": [
         {
-            "loc": ["body", "item", "price"],
+            "loc": ["body", "price"],
             "msg": "field required",
             "type": "value_error.missing",
         }
@@ -104,7 +104,7 @@ price_missing = {
 price_not_float = {
     "detail": [
         {
-            "loc": ["body", "item", "price"],
+            "loc": ["body", "price"],
             "msg": "value is not a valid float",
             "type": "type_error.float",
         }
@@ -114,12 +114,12 @@ price_not_float = {
 name_price_missing = {
     "detail": [
         {
-            "loc": ["body", "item", "name"],
+            "loc": ["body", "name"],
             "msg": "field required",
             "type": "value_error.missing",
         },
         {
-            "loc": ["body", "item", "price"],
+            "loc": ["body", "price"],
             "msg": "field required",
             "type": "value_error.missing",
         },
@@ -128,11 +128,7 @@ name_price_missing = {
 
 body_missing = {
     "detail": [
-        {
-            "loc": ["body", "item"],
-            "msg": "field required",
-            "type": "value_error.missing",
-        }
+        {"loc": ["body"], "msg": "field required", "type": "value_error.missing",}
     ]
 }
 
index 8a9f3953310820a589728a55371009fb8f9ad555..55859eb2b07f659e39ed489a41980ab2692bba53 100644 (file)
@@ -95,7 +95,7 @@ def test_post_invalid_body():
     assert response.json() == {
         "detail": [
             {
-                "loc": ["body", "weights", "__key__"],
+                "loc": ["body", "__key__"],
                 "msg": "value is not a valid integer",
                 "type": "type_error.integer",
             }
index 59daaf73bbf9f72c96138c90734bceffe49eb994..170065f64670b5ad67949d759862826a33749710 100644 (file)
@@ -18,7 +18,7 @@ def test_exception_handler_body_access():
             "body": '{"numbers": [1, 2, 3]}',
             "errors": [
                 {
-                    "loc": ["body", "numbers"],
+                    "loc": ["body"],
                     "msg": "value is not a valid list",
                     "type": "type_error.list",
                 }
index f974466d15979f311a278593e8259bf113b0d082..083f5141cd40b139175f99e9d06c1d40d5569846 100644 (file)
@@ -92,7 +92,7 @@ def test_post_validation_error():
     assert response.json() == {
         "detail": [
             {
-                "loc": ["body", "item", "size"],
+                "loc": ["body", "size"],
                 "msg": "value is not a valid integer",
                 "type": "type_error.integer",
             }