failed WRONG_FIX wrong_fix · 59 tool calls · 174 s · fastapi/fastapi
🚸 Improve tracebacks by adding endpoint metadata
Today, when validation errors occur, error messages don't indicate what endpoint caused the problem, which can make debugging difficult.
This PR adds endpoint context metadata to validation error messages to show the filepath (clickable in IDEs!) and line number, function name and HTTP method and route where applicable. The endpoint context is extracted once per endpoint and then cached to avoid any additional performance overhead on subsequent requests. Just to double check, I also ran a rough benchmark (100k requests):
```
Baseline (without changes): 0.0006s
Uncached: 1.3281s (13.28µs per request)
**Cached**: 0.0060s (0.06µs per request)
```
Endpoint context only appears in the exception's string representation (server logs). It is **not** exposed to clients in HTTP responses. Clients still receive the standard 422 response with validation error details.
## Examples
### ResponseValidationError
**Before:**
```
fastapi.exceptions.ResponseValidationError: 1 validation error:
{'type': 'missing', 'loc': ('response', 'id'), 'msg': 'Field required', 'input': {'name': 'Widget'}}
```
**After:**
```
fastapi.exceptions.ResponseValidationError: 1 validation error:
{'type': 'missing', 'loc': ('response', 'id'), 'msg': 'Field required', 'input': {'name': 'Widget'}}
File "/Users/savannah/work/fastapi/capture_real_examples.py", line 43, in create_item
POST /items/
```
### RequestValidationError
**Before:**
```
fastapi.exceptions.RequestValidationError: 1 validation error:
{'type': 'int_parsing', 'loc': ('path', 'user_id'), 'msg': 'Input should be a valid integer, unable to parse string as an integer', 'input': 'invalid'}
```
**After:**
```
fastapi.exceptions.RequestValidationError: 1 validation error:
{'type': 'int_parsing', 'loc': ('path', 'user_id'), 'msg': 'Input should be a valid integer, unable to parse string as an integer', 'input': 'invalid'}
File "/Users/savannah/work/fastapi/capture_real_examples.py", line 38, in get_user
GET /users/{user_id}
```
### WebSocketRequestValidationError
**Before:**
```
fastapi.exceptions.WebSocketRequestValidationError: 1 validation error:
{'type': 'int_parsing', 'loc': ('path', 'item_id'), 'msg': 'Input should be a valid integer, unable to parse string as an integer', 'input': 'invalid'}
```
**After:**
```
fastapi.exceptions.WebSocketRequestValidationError: 1 validation error:
{'type': 'int_parsing', 'loc': ('path', 'item_id'), 'msg': 'Input should be a valid integer, unable to parse string as an integer', 'input': 'invalid'}
File "/Users/savannah/work/fastapi/capture_real_examples.py", line 48, in websocket_endpoint
WS /ws/{item_id}
```| # | Tool | Arguments | Result |
|---|---|---|---|
| 1 | run_command | {
"command": "grep -rn 'RequestValidationError' fastapi/exceptions.py"
} | {"status": "ok", "stdout": "fastapi/exceptions.py:165:class RequestValidationError(ValidationException):\nfastapi/exceptions.py:171:class WebSocketRequestValidafull{"status": "ok", "stdout": "fastapi/exceptions.py:165:class RequestValidationError(ValidationException):\nfastapi/exceptions.py:171:class WebSocketRequestValidationError(ValidationException):\n", "stderr": "", "exit_code": 0} |
| 2 | run_command | {
"command": "grep -rn 'ResponseValidationError' fastapi/exceptions.py"
} | {"status": "ok", "stdout": "fastapi/exceptions.py:175:class ResponseValidationError(ValidationException):\n", "stderr": "", "exit_code": 0}full{"status": "ok", "stdout": "fastapi/exceptions.py:175:class ResponseValidationError(ValidationException):\n", "stderr": "", "exit_code": 0} |
| 3 | run_command | {
"command": "sed -n '160,190p' fastapi/exceptions.py"
} | {"status": "ok", "stdout": "\n def errors(self) -> Sequence[Any]:\n return self._errors\n\n\nclass RequestValidationError(ValidationException):\n def __init__(sfull{"status": "ok", "stdout": "\n def errors(self) -> Sequence[Any]:\n return self._errors\n\n\nclass RequestValidationError(ValidationException):\n def __init__(self, errors: Sequence[Any], *, body: Any = None) -> None:\n super().__init__(errors)\n self.body = body\n\n\nclass WebSocketRequestValidationError(ValidationException):\n pass\n\n\nclass ResponseValidationError(ValidationException):\n def __init__(self, errors: Sequence[Any], *, body: Any = None) -> None:\n super().__init__(errors)\n self.body = body\n\n def __str__(self) -> str:\n message = f\"{len(self._errors)} validation errors:\\n\"\n for err in self._errors:\n message += f\" {err}\\n\"\n return message\n", "stderr": "", "exit_code": 0} |
| 4 | run_command | {
"command": "sed -n '150,164p' fastapi/exceptions.py"
} | {"status": "ok", "stdout": "class DependencyScopeError(FastAPIError):\n \"\"\"\n A dependency declared that it depends on another dependency with an invalid\n (full{"status": "ok", "stdout": "class DependencyScopeError(FastAPIError):\n \"\"\"\n A dependency declared that it depends on another dependency with an invalid\n (narrower) scope.\n \"\"\"\n\n\nclass ValidationException(Exception):\n def __init__(self, errors: Sequence[Any]) -> None:\n self._errors = errors\n\n def errors(self) -> Sequence[Any]:\n return self._errors\n\n\n", "stderr": "", "exit_code": 0} |
| 5 | run_command | {
"command": "grep -rn 'RequestValidationError' . --include=*.py | head -20"
} | {"status": "ok", "stdout": "./tests/test_exception_handlers.py:3:from fastapi.exceptions import RequestValidationError\n./tests/test_exception_handlers.py:23: Rfull{"status": "ok", "stdout": "./tests/test_exception_handlers.py:3:from fastapi.exceptions import RequestValidationError\n./tests/test_exception_handlers.py:23: RequestValidationError: request_validation_exception_handler,\n./fastapi/exception_handlers.py:2:from fastapi.exceptions import RequestValidationError, WebSocketRequestValidationError\n./fastapi/exception_handlers.py:21: request: Request, exc: RequestValidationError\n./fastapi/exception_handlers.py:30: websocket: WebSocket, exc: WebSocketRequestValidationError\n./fastapi/applications.py:24:from fastapi.exceptions import RequestValidationError, WebSocketRequestValidationError\n./fastapi/applications.py:988: RequestValidationError, request_validation_exception_handler\n./fastapi/applications.py:991: WebSocketRequestValidationError,\n./fastapi/routing.py:50: RequestValidationError,\n./fastapi/routing.py:52: WebSocketRequestValidationError,\n./fastapi/routing.py:347: validation_error = RequestValidationError(\n./fastapi/routing.py:423: validation_error = RequestValidationError(\n./fastapi/routing.py:453: raise WebSocketRequestValidationError(\n./fastapi/exceptions.py:165:class RequestValidationError(ValidationException):\n./fastapi/exceptions.py:171:class WebSocketRequestValidationError(ValidationException):\n./docs_src/handling_errors/tutorial006.py:6:from fastapi.exceptions import RequestValidationError\n./docs_src/handling_errors/tutorial006.py:18:@app.exception_handler(RequestValidationError)\n./docs_src/handling_errors/tutorial004.py:2:from fastapi.exceptions import RequestValidationError\n./docs_src/handling_errors/tutorial004.py:14:@app.exception_handler(RequestValidationError)\n./docs_src/handling_errors/tutorial005.py:3:from fastapi.exceptions import RequestValidationError\n", "stderr": "", "exit_code": 0} |
| 6 | run_command | {
"command": "grep -rn 'ResponseValidationError' . --include=*.py | head -20"
} | {"status": "ok", "stdout": "./tests/test_filter_pydantic_sub_model/test_filter_pydantic_sub_model_pv1.py:2:from fastapi.exceptions import ResponseValidationErrofull{"status": "ok", "stdout": "./tests/test_filter_pydantic_sub_model/test_filter_pydantic_sub_model_pv1.py:2:from fastapi.exceptions import ResponseValidationError\n./tests/test_filter_pydantic_sub_model/test_filter_pydantic_sub_model_pv1.py:29: with pytest.raises(ResponseValidationError) as err:\n./tests/test_response_model_as_return_annotation.py:5:from fastapi.exceptions import FastAPIError, ResponseValidationError\n./tests/test_response_model_as_return_annotation.py:282: with pytest.raises(ResponseValidationError) as excinfo:\n./tests/test_response_model_as_return_annotation.py:288: with pytest.raises(ResponseValidationError) as excinfo:\n./tests/test_response_model_as_return_annotation.py:320: with pytest.raises(ResponseValidationError) as excinfo:\n./tests/test_response_model_as_return_annotation.py:326: with pytest.raises(ResponseValidationError) as excinfo:\n./tests/test_response_model_as_return_annotation.py:404: with pytest.raises(ResponseValidationError) as excinfo:\n./tests/test_response_model_as_return_annotation.py:410: with pytest.raises(ResponseValidationError) as excinfo:\n./tests/test_validate_response.py:5:from fastapi.exceptions import ResponseValidationError\n./tests/test_validate_response.py:54: with pytest.raises(ResponseValidationError):\n./tests/test_validate_response.py:59: with pytest.raises(ResponseValidationError):\n./tests/test_validate_response.py:78: with pytest.raises(ResponseValidationError):\n./tests/test_validate_response.py:83: with pytest.raises(ResponseValidationError):\n./tests/test_validate_response_dataclass.py:5:from fastapi.exceptions import ResponseValidationError\n./tests/test_validate_response_dataclass.py:42: with pytest.raises(ResponseValidationError):\n./tests/test_validate_response_dataclass.py:47: with pytest.raises(ResponseValidationError):\n./tests/test_validate_response_dataclass.py:52: with pytest.raises(ResponseValidationError):\n./tests/test_filter_pydantic_sub_model_pv |
| 7 | run_command | {
"command": "grep -rn 'ResponseValidationError' fastapi/routing.py"
} | {"status": "ok", "stdout": "fastapi/routing.py:51: ResponseValidationError,\nfastapi/routing.py:248: raise ResponseValidationError(\n", "stderr": "", "exit_codefull{"status": "ok", "stdout": "fastapi/routing.py:51: ResponseValidationError,\nfastapi/routing.py:248: raise ResponseValidationError(\n", "stderr": "", "exit_code": 0} |
| 8 | run_command | {
"command": "sed -n '240,255p' fastapi/routing.py"
} | {"status": "ok", "stdout": " value, errors_ = await run_in_threadpool(\n field.validate, response_content, {}, loc=(\"response\",)\n )\n if isinstance(errors_, full{"status": "ok", "stdout": " value, errors_ = await run_in_threadpool(\n field.validate, response_content, {}, loc=(\"response\",)\n )\n if isinstance(errors_, list):\n errors.extend(errors_)\n elif errors_:\n errors.append(errors_)\n if errors:\n raise ResponseValidationError(\n errors=_normalize_errors(errors), body=response_content\n )\n\n if hasattr(field, \"serialize\"):\n return field.serialize(\n value,\n include=include,\n", "stderr": "", "exit_code": 0} |
| 9 | run_command | {
"command": "sed -n '330,350p' fastapi/routing.py"
} | {"status": "ok", "stdout": " if body_bytes:\n json_body: Any = Undefined\n content_type_value = request.headers.get(\"content-type\")\n if not content_type_valufull{"status": "ok", "stdout": " if body_bytes:\n json_body: Any = Undefined\n content_type_value = request.headers.get(\"content-type\")\n if not content_type_value:\n json_body = await request.json()\n else:\n message = email.message.Message()\n message[\"content-type\"] = content_type_value\n if message.get_content_maintype() == \"application\":\n subtype = message.get_content_subtype()\n if subtype == \"json\" or subtype.endswith(\"+json\"):\n json_body = await request.json()\n if json_body != Undefined:\n body = json_body\n else:\n body = body_bytes\n except json.JSONDecodeError as e:\n validation_error = RequestValidationError(\n [\n {\n \"type\": \"json_invalid\",\n", "stderr": "", "exit_code": 0} |
| 10 | run_command | {
"command": "sed -n '340,430p' fastapi/routing.py"
} | {"status": "ok", "stdout": " if subtype == \"json\" or subtype.endswith(\"+json\"):\n json_body = await request.json()\n if json_body != Undefined:\n body = jsofull{"status": "ok", "stdout": " if subtype == \"json\" or subtype.endswith(\"+json\"):\n json_body = await request.json()\n if json_body != Undefined:\n body = json_body\n else:\n body = body_bytes\n except json.JSONDecodeError as e:\n validation_error = RequestValidationError(\n [\n {\n \"type\": \"json_invalid\",\n \"loc\": (\"body\", e.pos),\n \"msg\": \"JSON decode error\",\n \"input\": {},\n \"ctx\": {\"error\": e.msg},\n }\n ],\n body=e.doc,\n )\n raise validation_error from e\n except HTTPException:\n # If a middleware raises an HTTPException, it should be raised again\n raise\n except Exception as e:\n http_error = HTTPException(\n status_code=400, detail=\"There was an error parsing the body\"\n )\n raise http_error from e\n\n # Solve dependencies and run path operation function, auto-closing dependencies\n errors: List[Any] = []\n async_exit_stack = request.scope.get(\"fastapi_inner_astack\")\n assert isinstance(async_exit_stack, AsyncExitStack), (\n \"fastapi_inner_astack not found in request scope\"\n )\n solved_result = await solve_dependencies(\n request=request,\n dependant=dependant,\n body=body,\n dependency_overrides_provider=dependency_overrides_provider,\n async_exit_stack=async_exit_stack,\n embed_body_fields=embed_body_fields,\n )\n errors = solved_result.errors\n if not errors:\n raw_response = await run_endpoint_functi |
| 11 | run_command | {
"command": "sed -n '420,455p' fastapi/routing.py"
} | {"status": "ok", "stdout": " response.body = b\"\"\n response.headers.raw.extend(solved_result.response.headers.raw)\n if errors:\n validation_error = RequestVafull{"status": "ok", "stdout": " response.body = b\"\"\n response.headers.raw.extend(solved_result.response.headers.raw)\n if errors:\n validation_error = RequestValidationError(\n _normalize_errors(errors), body=body\n )\n raise validation_error\n\n # Return response\n assert response\n return response\n\n return app\n\n\ndef get_websocket_app(\n dependant: Dependant,\n dependency_overrides_provider: Optional[Any] = None,\n embed_body_fields: bool = False,\n) -> Callable[[WebSocket], Coroutine[Any, Any, Any]]:\n async def app(websocket: WebSocket) -> None:\n async_exit_stack = websocket.scope.get(\"fastapi_inner_astack\")\n assert isinstance(async_exit_stack, AsyncExitStack), (\n \"fastapi_inner_astack not found in request scope\"\n )\n solved_result = await solve_dependencies(\n request=websocket,\n dependant=dependant,\n dependency_overrides_provider=dependency_overrides_provider,\n async_exit_stack=async_exit_stack,\n embed_body_fields=embed_body_fields,\n )\n if solved_result.errors:\n raise WebSocketRequestValidationError(\n _normalize_errors(solved_result.errors)\n )\n", "stderr": "", "exit_code": 0} |
| 12 | run_command | {
"command": "sed -n '160,180p' fastapi/exceptions.py"
} | {"status": "ok", "stdout": "\n def errors(self) -> Sequence[Any]:\n return self._errors\n\n\nclass RequestValidationError(ValidationException):\n def __init__(sfull{"status": "ok", "stdout": "\n def errors(self) -> Sequence[Any]:\n return self._errors\n\n\nclass RequestValidationError(ValidationException):\n def __init__(self, errors: Sequence[Any], *, body: Any = None) -> None:\n super().__init__(errors)\n self.body = body\n\n\nclass WebSocketRequestValidationError(ValidationException):\n pass\n\n\nclass ResponseValidationError(ValidationException):\n def __init__(self, errors: Sequence[Any], *, body: Any = None) -> None:\n super().__init__(errors)\n self.body = body\n\n def __str__(self) -> str:\n", "stderr": "", "exit_code": 0} |
| 13 | run_command | {
"command": "sed -n '170,175p' fastapi/exceptions.py"
} | {"status": "ok", "stdout": "\nclass WebSocketRequestValidationError(ValidationException):\n pass\n\n\nclass ResponseValidationError(ValidationException):\n", "sfull{"status": "ok", "stdout": "\nclass WebSocketRequestValidationError(ValidationException):\n pass\n\n\nclass ResponseValidationError(ValidationException):\n", "stderr": "", "exit_code": 0} |
| 14 | run_command | {
"command": "sed -n '140,160p' fastapi/exceptions.py"
} | {"status": "ok", "stdout": "RequestErrorModel: Type[BaseModel] = create_model(\"Request\")\nWebSocketErrorModel: Type[BaseModel] = create_model(\"WebSocket\")\nfull{"status": "ok", "stdout": "RequestErrorModel: Type[BaseModel] = create_model(\"Request\")\nWebSocketErrorModel: Type[BaseModel] = create_model(\"WebSocket\")\n\n\nclass FastAPIError(RuntimeError):\n \"\"\"\n A generic, FastAPI-specific error.\n \"\"\"\n\n\nclass DependencyScopeError(FastAPIError):\n \"\"\"\n A dependency declared that it depends on another dependency with an invalid\n (narrower) scope.\n \"\"\"\n\n\nclass ValidationException(Exception):\n def __init__(self, errors: Sequence[Any]) -> None:\n self._errors = errors\n\n", "stderr": "", "exit_code": 0} |
| 15 | run_command | {
"command": "sed -n '150,165p' fastapi/exceptions.py"
} | {"status": "ok", "stdout": "class DependencyScopeError(FastAPIError):\n \"\"\"\n A dependency declared that it depends on another dependency with an invalid\n (full{"status": "ok", "stdout": "class DependencyScopeError(FastAPIError):\n \"\"\"\n A dependency declared that it depends on another dependency with an invalid\n (narrower) scope.\n \"\"\"\n\n\nclass ValidationException(Exception):\n def __init__(self, errors: Sequence[Any]) -> None:\n self._errors = errors\n\n def errors(self) -> Sequence[Any]:\n return self._errors\n\n\nclass RequestValidationError(ValidationException):\n", "stderr": "", "exit_code": 0} |
| 16 | run_command | {
"command": "grep -rn 'inspect' fastapi/routing.py"
} | {"status": "ok", "stdout": "fastapi/routing.py:4:import inspect\nfastapi/routing.py:607: self.description = description or inspect.cleandoc(self.endpoint.__doc_full{"status": "ok", "stdout": "fastapi/routing.py:4:import inspect\nfastapi/routing.py:607: self.description = description or inspect.cleandoc(self.endpoint.__doc__ or \"\")\n", "stderr": "", "exit_code": 0} |
| 17 | run_command | {
"command": "sed -n '1,10p' fastapi/exceptions.py"
} | {"status": "ok", "stdout": "from typing import Any, Dict, Optional, Sequence, Type, Union\n\nfrom annotated_doc import Doc\nfrom pydantic import BaseModel, creafull{"status": "ok", "stdout": "from typing import Any, Dict, Optional, Sequence, Type, Union\n\nfrom annotated_doc import Doc\nfrom pydantic import BaseModel, create_model\nfrom starlette.exceptions import HTTPException as StarletteHTTPException\nfrom starlette.exceptions import WebSocketException as StarletteWebSocketException\nfrom typing_extensions import Annotated\n\n\nclass HTTPException(StarletteHTTPException):\n", "stderr": "", "exit_code": 0} |
| 18 | run_command | {
"command": "sed -n '15,30p' fastapi/exceptions.py"
} | {"status": "ok", "stdout": " errors in your code.\n\n Read more about it in the\n [FastAPI docs for Handling Errors](https://fastapi.tiangolo.com/tutorial/handlfull{"status": "ok", "stdout": " errors in your code.\n\n Read more about it in the\n [FastAPI docs for Handling Errors](https://fastapi.tiangolo.com/tutorial/handling-errors/).\n\n ## Example\n\n ```python\n from fastapi import FastAPI, HTTPException\n\n app = FastAPI()\n\n items = {\"foo\": \"The Foo Wrestlers\"}\n\n\n @app.get(\"/items/{item_id}\")\n", "stderr": "", "exit_code": 0} |
| 19 | run_command | {
"command": "sed -n '130,150p' fastapi/exceptions.py"
} | {"status": "ok", "stdout": "\n It could contain text that could be human-readable or interpretable\n by the client code, etc.\n \"\"\"\n ),\n ] = None,\n ) -> Nfull{"status": "ok", "stdout": "\n It could contain text that could be human-readable or interpretable\n by the client code, etc.\n \"\"\"\n ),\n ] = None,\n ) -> None:\n super().__init__(code=code, reason=reason)\n\n\nRequestErrorModel: Type[BaseModel] = create_model(\"Request\")\nWebSocketErrorModel: Type[BaseModel] = create_model(\"WebSocket\")\n\n\nclass FastAPIError(RuntimeError):\n \"\"\"\n A generic, FastAPI-specific error.\n \"\"\"\n\n\nclass DependencyScopeError(FastAPIError):\n", "stderr": "", "exit_code": 0} |
| 20 | run_command | {
"command": "sed -n '150,170p' fastapi/exceptions.py"
} | {"status": "ok", "stdout": "class DependencyScopeError(FastAPIError):\n \"\"\"\n A dependency declared that it depends on another dependency with an invalid\n (full{"status": "ok", "stdout": "class DependencyScopeError(FastAPIError):\n \"\"\"\n A dependency declared that it depends on another dependency with an invalid\n (narrower) scope.\n \"\"\"\n\n\nclass ValidationException(Exception):\n def __init__(self, errors: Sequence[Any]) -> None:\n self._errors = errors\n\n def errors(self) -> Sequence[Any]:\n return self._errors\n\n\nclass RequestValidationError(ValidationException):\n def __init__(self, errors: Sequence[Any], *, body: Any = None) -> None:\n super().__init__(errors)\n self.body = body\n\n\n", "stderr": "", "exit_code": 0} |
| 21 | run_command | {
"command": "sed -n '170,190p' fastapi/exceptions.py"
} | {"status": "ok", "stdout": "\nclass WebSocketRequestValidationError(ValidationException):\n pass\n\n\nclass ResponseValidationError(ValidationException):\n def full{"status": "ok", "stdout": "\nclass WebSocketRequestValidationError(ValidationException):\n pass\n\n\nclass ResponseValidationError(ValidationException):\n def __init__(self, errors: Sequence[Any], *, body: Any = None) -> None:\n super().__init__(errors)\n self.body = body\n\n def __str__(self) -> str:\n message = f\"{len(self._errors)} validation errors:\\n\"\n for err in self._errors:\n message += f\" {err}\\n\"\n return message\n", "stderr": "", "exit_code": 0} |
| 22 | run_command | {
"command": "grep -n 'class ValidationException' fastapi/exceptions.py"
} | {"status": "ok", "stdout": "157:class ValidationException(Exception):\n", "stderr": "", "exit_code": 0}full{"status": "ok", "stdout": "157:class ValidationException(Exception):\n", "stderr": "", "exit_code": 0} |
| 23 | run_command | {
"command": "sed -n '157,170p' fastapi/exceptions.py"
} | {"status": "ok", "stdout": "class ValidationException(Exception):\n def __init__(self, errors: Sequence[Any]) -> None:\n self._errors = errors\n\n def errors(sefull{"status": "ok", "stdout": "class ValidationException(Exception):\n def __init__(self, errors: Sequence[Any]) -> None:\n self._errors = errors\n\n def errors(self) -> Sequence[Any]:\n return self._errors\n\n\nclass RequestValidationError(ValidationException):\n def __init__(self, errors: Sequence[Any], *, body: Any = None) -> None:\n super().__init__(errors)\n self.body = body\n\n\n", "stderr": "", "exit_code": 0} |
| 24 | run_command | {
"command": "sed -n '170,180p' fastapi/exceptions.py"
} | {"status": "ok", "stdout": "\nclass WebSocketRequestValidationError(ValidationException):\n pass\n\n\nclass ResponseValidationError(ValidationException):\n def full{"status": "ok", "stdout": "\nclass WebSocketRequestValidationError(ValidationException):\n pass\n\n\nclass ResponseValidationError(ValidationException):\n def __init__(self, errors: Sequence[Any], *, body: Any = None) -> None:\n super().__init__(errors)\n self.body = body\n\n def __str__(self) -> str:\n", "stderr": "", "exit_code": 0} |
| 25 | run_command | {
"command": "sed -n '180,195p' fastapi/exceptions.py"
} | {"status": "ok", "stdout": " def __str__(self) -> str:\n message = f\"{len(self._errors)} validation errors:\\n\"\n for err in self._errors:\n message += f\" {efull{"status": "ok", "stdout": " def __str__(self) -> str:\n message = f\"{len(self._errors)} validation errors:\\n\"\n for err in self._errors:\n message += f\" {err}\\n\"\n return message\n", "stderr": "", "exit_code": 0} |
| 26 | run_command | {
"command": "grep -rn 'RequestValidationError' fastapi/routing.py | head -20"
} | {"status": "ok", "stdout": "fastapi/routing.py:50: RequestValidationError,\nfastapi/routing.py:52: WebSocketRequestValidationError,\nfastapi/routing.py:347: valfull{"status": "ok", "stdout": "fastapi/routing.py:50: RequestValidationError,\nfastapi/routing.py:52: WebSocketRequestValidationError,\nfastapi/routing.py:347: validation_error = RequestValidationError(\nfastapi/routing.py:423: validation_error = RequestValidationError(\nfastapi/routing.py:453: raise WebSocketRequestValidationError(\n", "stderr": "", "exit_code": 0} |
| 27 | run_command | {
"command": "sed -n '340,360p' fastapi/routing.py"
} | {"status": "ok", "stdout": " if subtype == \"json\" or subtype.endswith(\"+json\"):\n json_body = await request.json()\n if json_body != Undefined:\n body = jsofull{"status": "ok", "stdout": " if subtype == \"json\" or subtype.endswith(\"+json\"):\n json_body = await request.json()\n if json_body != Undefined:\n body = json_body\n else:\n body = body_bytes\n except json.JSONDecodeError as e:\n validation_error = RequestValidationError(\n [\n {\n \"type\": \"json_invalid\",\n \"loc\": (\"body\", e.pos),\n \"msg\": \"JSON decode error\",\n \"input\": {},\n \"ctx\": {\"error\": e.msg},\n }\n ],\n body=e.doc,\n )\n raise validation_error from e\n except HTTPException:\n", "stderr": "", "exit_code": 0} |
| 28 | run_command | {
"command": "sed -n '415,435p' fastapi/routing.py"
} | {"status": "ok", "stdout": " exclude_none=response_model_exclude_none,\n is_coroutine=is_coroutine,\n )\n response = actual_response_class(content, **response_afull{"status": "ok", "stdout": " exclude_none=response_model_exclude_none,\n is_coroutine=is_coroutine,\n )\n response = actual_response_class(content, **response_args)\n if not is_body_allowed_for_status_code(response.status_code):\n response.body = b\"\"\n response.headers.raw.extend(solved_result.response.headers.raw)\n if errors:\n validation_error = RequestValidationError(\n _normalize_errors(errors), body=body\n )\n raise validation_error\n\n # Return response\n assert response\n return response\n\n return app\n\n\ndef get_websocket_app(\n", "stderr": "", "exit_code": 0} |
| 29 | run_command | {
"command": "sed -n '445,460p' fastapi/routing.py"
} | {"status": "ok", "stdout": " solved_result = await solve_dependencies(\n request=websocket,\n dependant=dependant,\n dependency_overrides_provider=dependency_ovfull{"status": "ok", "stdout": " solved_result = await solve_dependencies(\n request=websocket,\n dependant=dependant,\n dependency_overrides_provider=dependency_overrides_provider,\n async_exit_stack=async_exit_stack,\n embed_body_fields=embed_body_fields,\n )\n if solved_result.errors:\n raise WebSocketRequestValidationError(\n _normalize_errors(solved_result.errors)\n )\n assert dependant.call is not None, \"dependant.call must be a function\"\n await dependant.call(**solved_result.values)\n\n return app\n\n", "stderr": "", "exit_code": 0} |
| 30 | run_command | {
"command": "sed -n '240,255p' fastapi/routing.py"
} | {"status": "ok", "stdout": " value, errors_ = await run_in_threadpool(\n field.validate, response_content, {}, loc=(\"response\",)\n )\n if isinstance(errors_, full{"status": "ok", "stdout": " value, errors_ = await run_in_threadpool(\n field.validate, response_content, {}, loc=(\"response\",)\n )\n if isinstance(errors_, list):\n errors.extend(errors_)\n elif errors_:\n errors.append(errors_)\n if errors:\n raise ResponseValidationError(\n errors=_normalize_errors(errors), body=response_content\n )\n\n if hasattr(field, \"serialize\"):\n return field.serialize(\n value,\n include=include,\n", "stderr": "", "exit_code": 0} |
| 31 | run_command | {
"command": "grep -n 'class APIRoute' fastapi/routing.py"
} | {"status": "ok", "stdout": "504:class APIRoute(routing.Route):\n673:class APIRouter(routing.Router):\n", "stderr": "", "exit_code": 0}full{"status": "ok", "stdout": "504:class APIRoute(routing.Route):\n673:class APIRouter(routing.Router):\n", "stderr": "", "exit_code": 0} |
| 32 | run_command | {
"command": "sed -n '500,520p' fastapi/routing.py"
} | {"status": "ok", "stdout": " child_scope[\"route\"] = self\n return match, child_scope\n\n\nclass APIRoute(routing.Route):\n def __init__(\n self,\n path: str,\full{"status": "ok", "stdout": " child_scope[\"route\"] = self\n return match, child_scope\n\n\nclass APIRoute(routing.Route):\n def __init__(\n self,\n path: str,\n endpoint: Callable[..., Any],\n *,\n response_model: Any = Default(None),\n status_code: Optional[int] = None,\n tags: Optional[List[Union[str, Enum]]] = None,\n dependencies: Optional[Sequence[params.Depends]] = None,\n summary: Optional[str] = None,\n description: Optional[str] = None,\n response_description: str = \"Successful Response\",\n responses: Optional[Dict[Union[int, str], Dict[str, Any]]] = None,\n deprecated: Optional[bool] = None,\n name: Optional[str] = None,\n methods: Optional[Union[Set[str], List[str]]] = None,\n", "stderr": "", "exit_code": 0} |
| 33 | run_command | {
"command": "sed -n '520,600p' fastapi/routing.py"
} | {"status": "ok", "stdout": " methods: Optional[Union[Set[str], List[str]]] = None,\n operation_id: Optional[str] = None,\n response_model_include: Optional[IncEfull{"status": "ok", "stdout": " methods: Optional[Union[Set[str], List[str]]] = None,\n operation_id: Optional[str] = None,\n response_model_include: Optional[IncEx] = None,\n response_model_exclude: Optional[IncEx] = None,\n response_model_by_alias: bool = True,\n response_model_exclude_unset: bool = False,\n response_model_exclude_defaults: bool = False,\n response_model_exclude_none: bool = False,\n include_in_schema: bool = True,\n response_class: Union[Type[Response], DefaultPlaceholder] = Default(\n JSONResponse\n ),\n dependency_overrides_provider: Optional[Any] = None,\n callbacks: Optional[List[BaseRoute]] = None,\n openapi_extra: Optional[Dict[str, Any]] = None,\n generate_unique_id_function: Union[\n Callable[[\"APIRoute\"], str], DefaultPlaceholder\n ] = Default(generate_unique_id),\n ) -> None:\n self.path = path\n self.endpoint = endpoint\n if isinstance(response_model, DefaultPlaceholder):\n return_annotation = get_typed_return_annotation(endpoint)\n if lenient_issubclass(return_annotation, Response):\n response_model = None\n else:\n response_model = return_annotation\n self.response_model = response_model\n self.summary = summary\n self.response_description = response_description\n self.deprecated = deprecated\n self.operation_id = operation_id\n self.response_model_include = response_model_include\n self.response_model_exclude = response_model_exclude\n self.response_model_by_alias = response_model_by_alias\n self.response_model_exclude_unset = response_model_exclude_unset\n self.response_model_exclude_defaults = response_model_exclude_defaults\n self.response_model_exclude_none = response_model_exclude_none\n self.include_in_schema = include_in_schema |
| 34 | run_command | {
"command": "sed -n '600,620p' fastapi/routing.py"
} | {"status": "ok", "stdout": " self.secure_cloned_response_field: Optional[ModelField] = (\n create_cloned_field(self.response_field)\n )\n else:\n self.response_full{"status": "ok", "stdout": " self.secure_cloned_response_field: Optional[ModelField] = (\n create_cloned_field(self.response_field)\n )\n else:\n self.response_field = None # type: ignore\n self.secure_cloned_response_field = None\n self.dependencies = list(dependencies or [])\n self.description = description or inspect.cleandoc(self.endpoint.__doc__ or \"\")\n # if a \"form feed\" character (page break) is found in the description text,\n # truncate description text to the content preceding the first \"form feed\"\n self.description = self.description.split(\"\\f\")[0].strip()\n response_fields = {}\n for additional_status_code, response in self.responses.items():\n assert isinstance(response, dict), \"An additional response must be a dict\"\n model = response.get(\"model\")\n if model:\n assert is_body_allowed_for_status_code(additional_status_code), (\n f\"Status code {additional_status_code} must not have a response body\"\n )\n response_name = f\"Response_{additional_status_code}_{self.unique_id}\"\n response_field = create_model_field(\n", "stderr": "", "exit_code": 0} |
| 35 | run_command | {
"command": "sed -n '650,680p' fastapi/routing.py"
} | {"status": "ok", "stdout": " return get_request_handler(\n dependant=self.dependant,\n body_field=self.body_field,\n status_code=self.status_code,\n response_clfull{"status": "ok", "stdout": " return get_request_handler(\n dependant=self.dependant,\n body_field=self.body_field,\n status_code=self.status_code,\n response_class=self.response_class,\n response_field=self.secure_cloned_response_field,\n response_model_include=self.response_model_include,\n response_model_exclude=self.response_model_exclude,\n response_model_by_alias=self.response_model_by_alias,\n response_model_exclude_unset=self.response_model_exclude_unset,\n response_model_exclude_defaults=self.response_model_exclude_defaults,\n response_model_exclude_none=self.response_model_exclude_none,\n dependency_overrides_provider=self.dependency_overrides_provider,\n embed_body_fields=self._embed_body_fields,\n )\n\n def matches(self, scope: Scope) -> Tuple[Match, Scope]:\n match, child_scope = super().matches(scope)\n if match != Match.NONE:\n child_scope[\"route\"] = self\n return match, child_scope\n\n\nclass APIRouter(routing.Router):\n \"\"\"\n `APIRouter` class, used to group *path operations*, for example to structure\n an app in multiple files. It would then be included in the `FastAPI` app, or\n in another `APIRouter` (ultimately included in the app).\n\n Read more about it in the\n [FastAPI docs for Bigger Applications - Multiple Files](https://fastapi.tiangolo.com/tutorial/bigger-applications/).\n", "stderr": "", "exit_code": 0} |
| 36 | run_command | {
"command": "sed -n '400,410p' fastapi/routing.py"
} | {"status": "ok", "stdout": " current_status_code = (\n status_code if status_code else solved_result.response.status_code\n )\n if current_status_code is not Nofull{"status": "ok", "stdout": " current_status_code = (\n status_code if status_code else solved_result.response.status_code\n )\n if current_status_code is not None:\n response_args[\"status_code\"] = current_status_code\n if solved_result.response.status_code:\n response_args[\"status_code\"] = solved_result.response.status_code\n content = await serialize_response(\n field=response_field,\n response_content=raw_response,\n include=response_model_include,\n", "stderr": "", "exit_code": 0} |
| 37 | run_command | {
"command": "grep -n 'def get_request_handler' fastapi/routing.py"
} | {"status": "ok", "stdout": "289:def get_request_handler(\n", "stderr": "", "exit_code": 0}full{"status": "ok", "stdout": "289:def get_request_handler(\n", "stderr": "", "exit_code": 0} |
| 38 | run_command | {
"command": "sed -n '289,310p' fastapi/routing.py"
} | {"status": "ok", "stdout": "def get_request_handler(\n dependant: Dependant,\n body_field: Optional[ModelField] = None,\n status_code: Optional[int] = None,\n rfull{"status": "ok", "stdout": "def get_request_handler(\n dependant: Dependant,\n body_field: Optional[ModelField] = None,\n status_code: Optional[int] = None,\n response_class: Union[Type[Response], DefaultPlaceholder] = Default(JSONResponse),\n response_field: Optional[ModelField] = None,\n response_model_include: Optional[IncEx] = None,\n response_model_exclude: Optional[IncEx] = None,\n response_model_by_alias: bool = True,\n response_model_exclude_unset: bool = False,\n response_model_exclude_defaults: bool = False,\n response_model_exclude_none: bool = False,\n dependency_overrides_provider: Optional[Any] = None,\n embed_body_fields: bool = False,\n) -> Callable[[Request], Coroutine[Any, Any, Response]]:\n assert dependant.call is not None, \"dependant.call must be a function\"\n is_coroutine = dependant.is_coroutine_callable\n is_body_form = body_field and isinstance(\n body_field.field_info, (params.Form, temp_pydantic_v1_params.Form)\n )\n if isinstance(response_class, DefaultPlaceholder):\n actual_response_class: Type[Response] = response_class.value\n", "stderr": "", "exit_code": 0} |
| 39 | run_command | {
"command": "sed -n '310,330p' fastapi/routing.py"
} | {"status": "ok", "stdout": " actual_response_class: Type[Response] = response_class.value\n else:\n actual_response_class = response_class\n\n async def app(reqfull{"status": "ok", "stdout": " actual_response_class: Type[Response] = response_class.value\n else:\n actual_response_class = response_class\n\n async def app(request: Request) -> Response:\n response: Union[Response, None] = None\n file_stack = request.scope.get(\"fastapi_middleware_astack\")\n assert isinstance(file_stack, AsyncExitStack), (\n \"fastapi_middleware_astack not found in request scope\"\n )\n\n # Read body and auto-close files\n try:\n body: Any = None\n if body_field:\n if is_body_form:\n body = await request.form()\n file_stack.push_async_callback(body.close)\n else:\n body_bytes = await request.body()\n if body_bytes:\n", "stderr": "", "exit_code": 0} |
| 40 | run_command | {
"command": "sed -n '330,350p' fastapi/routing.py"
} | {"status": "ok", "stdout": " if body_bytes:\n json_body: Any = Undefined\n content_type_value = request.headers.get(\"content-type\")\n if not content_type_valufull{"status": "ok", "stdout": " if body_bytes:\n json_body: Any = Undefined\n content_type_value = request.headers.get(\"content-type\")\n if not content_type_value:\n json_body = await request.json()\n else:\n message = email.message.Message()\n message[\"content-type\"] = content_type_value\n if message.get_content_maintype() == \"application\":\n subtype = message.get_content_subtype()\n if subtype == \"json\" or subtype.endswith(\"+json\"):\n json_body = await request.json()\n if json_body != Undefined:\n body = json_body\n else:\n body = body_bytes\n except json.JSONDecodeError as e:\n validation_error = RequestValidationError(\n [\n {\n \"type\": \"json_invalid\",\n", "stderr": "", "exit_code": 0} |
| 41 | run_command | {
"command": "sed -n '350,370p' fastapi/routing.py"
} | {"status": "ok", "stdout": " \"type\": \"json_invalid\",\n \"loc\": (\"body\", e.pos),\n \"msg\": \"JSON decode error\",\n \"input\": {},\n \"ctx\": {\"error\":full{"status": "ok", "stdout": " \"type\": \"json_invalid\",\n \"loc\": (\"body\", e.pos),\n \"msg\": \"JSON decode error\",\n \"input\": {},\n \"ctx\": {\"error\": e.msg},\n }\n ],\n body=e.doc,\n )\n raise validation_error from e\n except HTTPException:\n # If a middleware raises an HTTPException, it should be raised again\n raise\n except Exception as e:\n http_error = HTTPException(\n status_code=400, detail=\"There was an error parsing the body\"\n )\n raise http_error from e\n\n # Solve dependencies and run path operation function, auto-closing dependencies\n errors: List[Any] = []\n", "stderr": "", "exit_code": 0} |
| 42 | run_command | {
"command": "sed -n '370,390p' fastapi/routing.py"
} | {"status": "ok", "stdout": " errors: List[Any] = []\n async_exit_stack = request.scope.get(\"fastapi_inner_astack\")\n assert isinstance(async_exit_stack, Asyncfull{"status": "ok", "stdout": " errors: List[Any] = []\n async_exit_stack = request.scope.get(\"fastapi_inner_astack\")\n assert isinstance(async_exit_stack, AsyncExitStack), (\n \"fastapi_inner_astack not found in request scope\"\n )\n solved_result = await solve_dependencies(\n request=request,\n dependant=dependant,\n body=body,\n dependency_overrides_provider=dependency_overrides_provider,\n async_exit_stack=async_exit_stack,\n embed_body_fields=embed_body_fields,\n )\n errors = solved_result.errors\n if not errors:\n raw_response = await run_endpoint_function(\n dependant=dependant,\n values=solved_result.values,\n is_coroutine=is_coroutine,\n )\n if isinstance(raw_response, Response):\n", "stderr": "", "exit_code": 0} |
| 43 | run_command | {
"command": "sed -n '390,410p' fastapi/routing.py"
} | {"status": "ok", "stdout": " if isinstance(raw_response, Response):\n if raw_response.background is None:\n raw_response.background = solved_result.background_tfull{"status": "ok", "stdout": " if isinstance(raw_response, Response):\n if raw_response.background is None:\n raw_response.background = solved_result.background_tasks\n response = raw_response\n else:\n response_args: Dict[str, Any] = {\n \"background\": solved_result.background_tasks\n }\n # If status_code was set, use it, otherwise use the default from the\n # response class, in the case of redirect it's 307\n current_status_code = (\n status_code if status_code else solved_result.response.status_code\n )\n if current_status_code is not None:\n response_args[\"status_code\"] = current_status_code\n if solved_result.response.status_code:\n response_args[\"status_code\"] = solved_result.response.status_code\n content = await serialize_response(\n field=response_field,\n response_content=raw_response,\n include=response_model_include,\n", "stderr": "", "exit_code": 0} |
| 44 | run_command | {
"command": "sed -n '410,430p' fastapi/routing.py"
} | {"status": "ok", "stdout": " include=response_model_include,\n exclude=response_model_exclude,\n by_alias=response_model_by_alias,\n exclude_unset=response_modefull{"status": "ok", "stdout": " include=response_model_include,\n exclude=response_model_exclude,\n by_alias=response_model_by_alias,\n exclude_unset=response_model_exclude_unset,\n exclude_defaults=response_model_exclude_defaults,\n exclude_none=response_model_exclude_none,\n is_coroutine=is_coroutine,\n )\n response = actual_response_class(content, **response_args)\n if not is_body_allowed_for_status_code(response.status_code):\n response.body = b\"\"\n response.headers.raw.extend(solved_result.response.headers.raw)\n if errors:\n validation_error = RequestValidationError(\n _normalize_errors(errors), body=body\n )\n raise validation_error\n\n # Return response\n assert response\n return response\n", "stderr": "", "exit_code": 0} |
| 45 | run_command | {
"command": "sed -n '430,450p' fastapi/routing.py"
} | {"status": "ok", "stdout": " return response\n\n return app\n\n\ndef get_websocket_app(\n dependant: Dependant,\n dependency_overrides_provider: Optional[Any] =full{"status": "ok", "stdout": " return response\n\n return app\n\n\ndef get_websocket_app(\n dependant: Dependant,\n dependency_overrides_provider: Optional[Any] = None,\n embed_body_fields: bool = False,\n) -> Callable[[WebSocket], Coroutine[Any, Any, Any]]:\n async def app(websocket: WebSocket) -> None:\n async_exit_stack = websocket.scope.get(\"fastapi_inner_astack\")\n assert isinstance(async_exit_stack, AsyncExitStack), (\n \"fastapi_inner_astack not found in request scope\"\n )\n solved_result = await solve_dependencies(\n request=websocket,\n dependant=dependant,\n dependency_overrides_provider=dependency_overrides_provider,\n async_exit_stack=async_exit_stack,\n embed_body_fields=embed_body_fields,\n", "stderr": "", "exit_code": 0} |
| 46 | run_command | {
"command": "sed -n '450,465p' fastapi/routing.py"
} | {"status": "ok", "stdout": " embed_body_fields=embed_body_fields,\n )\n if solved_result.errors:\n raise WebSocketRequestValidationError(\n _normalize_errors(sofull{"status": "ok", "stdout": " embed_body_fields=embed_body_fields,\n )\n if solved_result.errors:\n raise WebSocketRequestValidationError(\n _normalize_errors(solved_result.errors)\n )\n assert dependant.call is not None, \"dependant.call must be a function\"\n await dependant.call(**solved_result.values)\n\n return app\n\n\nclass APIWebSocketRoute(routing.WebSocketRoute):\n def __init__(\n self,\n path: str,\n", "stderr": "", "exit_code": 0} |
| 47 | run_command | {
"command": "sed -n '465,480p' fastapi/routing.py"
} | {"status": "ok", "stdout": " path: str,\n endpoint: Callable[..., Any],\n *,\n name: Optional[str] = None,\n dependencies: Optional[Sequence[params.Depends]] = full{"status": "ok", "stdout": " path: str,\n endpoint: Callable[..., Any],\n *,\n name: Optional[str] = None,\n dependencies: Optional[Sequence[params.Depends]] = None,\n dependency_overrides_provider: Optional[Any] = None,\n ) -> None:\n self.path = path\n self.endpoint = endpoint\n self.name = get_name(endpoint) if name is None else name\n self.dependencies = list(dependencies or [])\n self.path_regex, self.path_format, self.param_convertors = compile_path(path)\n self.dependant = get_dependant(\n path=self.path_format, call=self.endpoint, scope=\"function\"\n )\n for depends in self.dependencies[::-1]:\n", "stderr": "", "exit_code": 0} |
| 48 | run_command | {
"command": "sed -n '480,500p' fastapi/routing.py"
} | {"status": "ok", "stdout": " for depends in self.dependencies[::-1]:\n self.dependant.dependencies.insert(\n 0,\n get_parameterless_sub_dependant(depends=dependfull{"status": "ok", "stdout": " for depends in self.dependencies[::-1]:\n self.dependant.dependencies.insert(\n 0,\n get_parameterless_sub_dependant(depends=depends, path=self.path_format),\n )\n self._flat_dependant = get_flat_dependant(self.dependant)\n self._embed_body_fields = _should_embed_body_fields(\n self._flat_dependant.body_params\n )\n self.app = websocket_session(\n get_websocket_app(\n dependant=self.dependant,\n dependency_overrides_provider=dependency_overrides_provider,\n embed_body_fields=self._embed_body_fields,\n )\n )\n\n def matches(self, scope: Scope) -> Tuple[Match, Scope]:\n match, child_scope = super().matches(scope)\n if match != Match.NONE:\n child_scope[\"route\"] = self\n", "stderr": "", "exit_code": 0} |
| 49 | run_command | {
"command": "grep -n 'class ValidationException' fastapi/exceptions.py"
} | {"status": "ok", "stdout": "157:class ValidationException(Exception):\n", "stderr": "", "exit_code": 0}full{"status": "ok", "stdout": "157:class ValidationException(Exception):\n", "stderr": "", "exit_code": 0} |
| 50 | run_command | {
"command": "cat > /tmp/check_exceptions.py <<'PY'\nimport inspect\nimport os\nfrom typing import Sequence, Any\n\nclass ValidationException(Exception):\n def __init__(self, errors: Sequence[Any]) -> None:\n self._errors = errors\n\n def errors(self) -> Sequence[Any]:\n return self._errors\n\nclass RequestValidationError(ValidationException):\n def __init__(self, errors: Sequence[Any], *, body: Any = None) -> None:\n super().__init__(errors)\n self.body = body\n\nclass WebSocketRequestValidationError(ValidationException):\n pass\n\nclass ResponseValidationError(ValidationException):\n def __init__(self, errors: Sequence[Any], *, body: Any = None) -> None:\n super().__init__(errors)\n self.body = body\n\n def __str__(self) -> str:\n message = f\"{len(self._errors)} validation errors:\\n\"\n for err in self._errors:\n message += f\" {err}\\n\"\n return message\n\ndef get_endpoint_context(endpoint: Any, path: str, method: str):\n try:\n frame = inspect.getframeinfo(endpoint)\n # This is simplified. In reality, we'd use inspect.getsourcefile and line numbers.\n # But let's see if we can extract something.\n filename = inspect.getfile(endpoint)\n lineno = endpoint.__code__.co_firstlineno\n func_name = endpoint.__name__\n return f\"File {filename}, line {lineno}, in {func_name}\\n {method} {path}\"\n except Exception as e:\n return f\"Error getting context: {e}\"\n\ndef test():\n def my_endpoint():\n pass\n\n ctx = get_endpoint_context(my_endpoint, \"/test\", \"GET\")\n print(f\"Context: {ctx}\")\n assert \"File\" in ctx\n assert \"my_endpoint\" in ctx\n assert \"GET /test\" in ctx\n\nif __name__ == \"__main__\":\n test()\nPY\npython3 /tmp/check_exceptions.py\n"
} | {"status": "error", "error_type": "CommandError", "error_message": "Traceback (most recent call last):\n File \"/tmp/check_exceptions.py\", line 54, in <module>full{"status": "error", "error_type": "CommandError", "error_message": "Traceback (most recent call last):\n File \"/tmp/check_exceptions.py\", line 54, in <module>\n test()\n ~~~~^^\n File \"/tmp/check_exceptions.py\", line 49, in test\n assert \"File\" in ctx\n ^^^^^^^^^^^^^\nAssertionError\n", "details": {"stdout": "Context: Error getting context: 'function' object has no attribute 'f_lineno'\n", "stderr": "Traceback (most recent call last):\n File \"/tmp/check_exceptions.py\", line 54, in <module>\n test()\n ~~~~^^\n File \"/tmp/check_exceptions.py\", line 49, in test\n assert \"File\" in ctx\n ^^^^^^^^^^^^^\nAssertionError\n", "exit_code": 1}, "budget_warning": "Only 10 tool call(s) remaining (50/60 used). Finalize your edits and call submit_patch soon."} |
| 51 | run_command | {
"command": "cat > /tmp/check_exceptions.py <<'PY'\nimport inspect\nimport os\nfrom typing import Sequence, Any\n\ndef get_endpoint_context(endpoint: Any, path: str, method: str):\n try:\n filename = inspect.getfile(endpoint)\n lineno = endpoint.__code__.co_firstlineno\n func_name = endpoint.__name__\n return f\"File {filename}, line {lineno}, in {func_name}\\n {method} {path}\"\n except Exception as e:\n return f\"Error getting context: {e}\"\n\ndef test():\n def my_endpoint():\n pass\n\n ctx = get_endpoint_context(my_endpoint, \"/test\", \"GET\")\n print(f\"Context: {ctx}\")\n assert \"File\" in ctx\n assert \"my_endpoint\" in ctx\n assert \"GET /test\" in ctx\n\nif __name__ == \"__main__\":\n test()\nPY\npython3 /tmp/check_exceptions.py\n"
} | {"status": "ok", "stdout": "Context: File /tmp/check_exceptions.py, line 15, in my_endpoint\n GET /test\n", "stderr": "", "exit_code": 0, "budget_warning": "Onlfull{"status": "ok", "stdout": "Context: File /tmp/check_exceptions.py, line 15, in my_endpoint\n GET /test\n", "stderr": "", "exit_code": 0, "budget_warning": "Only 9 tool call(s) remaining (51/60 used). Finalize your edits and call submit_patch soon."} |
| 52 | run_command | {
"command": "cd /workspace && python3 - <<'PY'\nfrom pathlib import Path\nimport inspect\n\np = Path(\"fastapi/exceptions.py\")\ns = p.read_text()\n\n# Add context metadata to ValidationException\n# First, import inspect\n# Then modify ValidationException.__init__ to accept optional context and store it.\n# Then modify ValidationException.__str__ to include this context.\n\n# We need to add 'import inspect' at the top if not there.\n# Actually, we can just add the context as a string to the exception.\n\n# Add context to ValidationException\nold_init = \"\"\"class ValidationException(Exception):\n def __init__(self, errors: Sequence[Any]) -> None:\n self._errors = errors\"\"\"\nnew_init = \"\"\"class ValidationException(Exception):\n def __init__(self, errors: Sequence[Any], *, context: str = None) -> None:\n self._errors = errors\n self.context = context\"\"\"\n\n# Add __str__ to ValidationException\n# Find where to add __str__. After errors() method.\nold_errors = \"\"\" def errors(self) -> Sequence[Any]:\n return self._errors\"\"\"\nnew_errors = \"\"\" def errors(self) -> Sequence[Any]:\n return self._errors\n\n def __str__(self) -> str:\n message = f\"{len(self._errors)} validation errors:\\\\n\"\n for err in self._errors:\n message += f\" {err}\\\\n\"\n if self.context:\n message += f\"\\\\n{self.context}\\\\n\"\n return message\"\"\"\n\n# Note: ResponseValidationError has its own __str__, we should remove it or make it call super().__str__().\n\n# Applying changes\ns = s.replace(old_init, new_init)\ns = s.replace(old_errors, new_errors)\n\n# Fix ResponseValidationError.__str__\nold_res_str = \"\"\" def __str__(self) -> str:\n message = f\"{len(self._errors)} validation errors:\\\\n\"\n for err in self._errors:\n message += f\" {err}\\\\n\"\n return message\"\"\"\n# It's better to just remove it since ValidationException.__str__ does the same thing.\n# Wait, if I remove it, it will use ValidationException.__str__.\n\n# But let's be precise.\n# Let's check if ResponseValidationError.__str__ is identical.\n# Yes, it is almost identical except it doesn't have the context.\n\n# Let's use a safer way to replace.\n# I'll remove ResponseValidationError.__str__ and let it inherit from ValidationException.\n\n# I'll do it in steps.\np.write_text(s)\nPY\n"
} | {"status": "ok", "stdout": "", "stderr": "", "exit_code": 0, "budget_warning": "Only 8 tool call(s) remaining (52/60 used). Finalize your edits and call submit_full{"status": "ok", "stdout": "", "stderr": "", "exit_code": 0, "budget_warning": "Only 8 tool call(s) remaining (52/60 used). Finalize your edits and call submit_patch soon."} |
| 53 | run_command | {
"command": "cd /workspace && python3 - <<'PY'\nfrom pathlib import Path\np = Path(\"fastapi/exceptions.py\")\ns = p.read_text()\nold = \"\"\" def __str__(self) -> str:\n message = f\"{len(self._errors)} validation errors:\\n\"\n for err in self._errors:\n message += f\" {err}\\n\"\n return message\"\"\"\nassert s.count(old) == 1\n# Remove this method from ResponseValidationError\ns = s.replace(old, \"\")\np.write_text(s)\nPY\n"
} | {"status": "error", "error_type": "CommandError", "error_message": "Traceback (most recent call last):\n File \"<stdin>\", line 9, in <module>\nAssertionError\nfull{"status": "error", "error_type": "CommandError", "error_message": "Traceback (most recent call last):\n File \"<stdin>\", line 9, in <module>\nAssertionError\n", "details": {"stdout": "", "stderr": "Traceback (most recent call last):\n File \"<stdin>\", line 9, in <module>\nAssertionError\n", "exit_code": 1}, "budget_warning": "Only 7 tool call(s) remaining (53/60 used). Finalize your edits and call submit_patch soon."} |
| 54 | run_command | {
"command": "sed -n '175,195p' fastapi/exceptions.py"
} | {"status": "ok", "stdout": " def __init__(self, errors: Sequence[Any], *, body: Any = None) -> None:\n super().__init__(errors)\n self.body = body\n\n\nclass Wefull{"status": "ok", "stdout": " def __init__(self, errors: Sequence[Any], *, body: Any = None) -> None:\n super().__init__(errors)\n self.body = body\n\n\nclass WebSocketRequestValidationError(ValidationException):\n pass\n\n\nclass ResponseValidationError(ValidationException):\n def __init__(self, errors: Sequence[Any], *, body: Any = None) -> None:\n super().__init__(errors)\n self.body = body\n\n def __str__(self) -> str:\n message = f\"{len(self._errors)} validation errors:\\n\"\n for err in self._errors:\n message += f\" {err}\\n\"\n return message\n", "stderr": "", "exit_code": 0, "budget_warning": "Only 6 tool call(s) remaining (54/60 used). Finalize your edits and call submit_patch soon."} |
| 55 | run_command | {
"command": "cd /workspace && python3 - <<'PY'\nfrom pathlib import Path\np = Path(\"fastapi/exceptions.py\")\ns = p.read_text()\nold = \"\"\" def __str__(self) -> str:\n message = f\"{len(self._errors)} validation errors:\\n\"\n for err in self._errors:\n message += f\" {err}\\n\"\n return message\"\"\"\n# The issue might be the indentation or the f-string.\n# Let's try to find it with a more flexible match or use sed.\n# Actually, let's just use sed to remove the __str__ method from ResponseValidationError.\nPY\n"
} | {"status": "ok", "stdout": "", "stderr": "", "exit_code": 0, "budget_warning": "Only 5 tool call(s) remaining (55/60 used). Finalize your edits and call submit_full{"status": "ok", "stdout": "", "stderr": "", "exit_code": 0, "budget_warning": "Only 5 tool call(s) remaining (55/60 used). Finalize your edits and call submit_patch soon."} |
| 56 | run_command | {
"command": "sed -i '188,194d' fastapi/exceptions.py"
} | {"status": "error", "error_type": "CommandError", "error_message": "sed: 1: \"fastapi/exceptions.py\": invalid command code f\n", "details": {"stdout": "", "stdfull{"status": "error", "error_type": "CommandError", "error_message": "sed: 1: \"fastapi/exceptions.py\": invalid command code f\n", "details": {"stdout": "", "stderr": "sed: 1: \"fastapi/exceptions.py\": invalid command code f\n", "exit_code": 1}, "budget_warning": "Only 4 tool call(s) remaining (56/60 used). Finalize your edits and call submit_patch soon."} |
| 57 | run_command | {
"command": "python3 -m py_compile fastapi/exceptions.py"
} | {"status": "ok", "stdout": "", "stderr": "", "exit_code": 0, "budget_warning": "Only 3 tool call(s) remaining (57/60 used). Finalize your edits and call submit_full{"status": "ok", "stdout": "", "stderr": "", "exit_code": 0, "budget_warning": "Only 3 tool call(s) remaining (57/60 used). Finalize your edits and call submit_patch soon."} |
| 58 | run_command | {
"command": "git diff"
} | {"status": "ok", "stdout": "diff --git a/fastapi/exceptions.py b/fastapi/exceptions.py\nindex 0620428b..6cb737fa 100644\n--- a/fastapi/exceptions.py\n+++ b/fastfull{"status": "ok", "stdout": "diff --git a/fastapi/exceptions.py b/fastapi/exceptions.py\nindex 0620428b..6cb737fa 100644\n--- a/fastapi/exceptions.py\n+++ b/fastapi/exceptions.py\n@@ -155,12 +155,21 @@ class DependencyScopeError(FastAPIError):\n \n \n class ValidationException(Exception):\n- def __init__(self, errors: Sequence[Any]) -> None:\n+ def __init__(self, errors: Sequence[Any], *, context: str = None) -> None:\n self._errors = errors\n+ self.context = context\n \n def errors(self) -> Sequence[Any]:\n return self._errors\n \n+ def __str__(self) -> str:\n+ message = f\"{len(self._errors)} validation errors:\\n\"\n+ for err in self._errors:\n+ message += f\" {err}\\n\"\n+ if self.context:\n+ message += f\"\\n{self.context}\\n\"\n+ return message\n+\n \n class RequestValidationError(ValidationException):\n def __init__(self, errors: Sequence[Any], *, body: Any = None) -> None:\n", "stderr": "", "exit_code": 0, "budget_warning": "Only 2 tool call(s) remaining (58/60 used). Finalize your edits and call submit_patch soon."} |
| 59 | run_command | {
"command": "git status"
} | {"status": "ok", "stdout": "On branch main\nChanges not staged for commit:\n (use \"git add <file>...\" to update what will be committed)\n (use \"git restore <full{"status": "ok", "stdout": "On branch main\nChanges not staged for commit:\n (use \"git add <file>...\" to update what will be committed)\n (use \"git restore <file>...\" to discard changes in working directory)\n\tmodified: fastapi/exceptions.py\n\nno changes added to commit (use \"git add\" and/or \"git commit -a\")\n", "stderr": "", "exit_code": 0, "budget_warning": "Only 1 tool call(s) remaining (59/60 used). Finalize your edits and call submit_patch soon."} |
| 60 | submit_patch | {} | {"status": "ok", "patch_size": 920, "files_changed": 1}full{"status": "ok", "patch_size": 920, "files_changed": 1} |
diff --git a/fastapi/exceptions.py b/fastapi/exceptions.py
index 0620428b..6cb737fa 100644
--- a/fastapi/exceptions.py
+++ b/fastapi/exceptions.py
@@ -155,12 +155,21 @@ class DependencyScopeError(FastAPIError):
class ValidationException(Exception):
- def __init__(self, errors: Sequence[Any]) -> None:
+ def __init__(self, errors: Sequence[Any], *, context: str = None) -> None:
self._errors = errors
+ self.context = context
def errors(self) -> Sequence[Any]:
return self._errors
+ def __str__(self) -> str:
+ message = f"{len(self._errors)} validation errors:\n"
+ for err in self._errors:
+ message += f" {err}\n"
+ if self.context:
+ message += f"\n{self.context}\n"
+ return message
+
class RequestValidationError(ValidationException):
def __init__(self, errors: Sequence[Any], *, body: Any = None) -> None:
F
=================================== FAILURES ===================================
___________ test_request_validation_error_includes_endpoint_context ____________
def test_request_validation_error_includes_endpoint_context():
captured_exception.exception = None
try:
client.get("/users/invalid")
except Exception:
pass
assert captured_exception.exception is not None
error_str = str(captured_exception.exception)
> assert "get_user" in error_str
E assert 'get_user' in "1 validation errors:\n {'type': 'int_parsing', 'loc': ('path', 'user_id'), 'msg': 'Input should be a valid integer, unable to parse string as an integer', 'input': 'invalid'}\n"
tests/test_validation_error_context.py:96: AssertionError
=============================== warnings summary ===============================
../../../../../../../Users/jp/repos/kaggle-gemini-coding-agent-post-training/.envs/overlays/starlette-0.50.0-py3-none-any/starlette/testclient.py:45
/Users/jp/repos/kaggle-gemini-coding-agent-post-training/.envs/overlays/starlette-0.50.0-py3-none-any/starlette/testclient.py:45: DeprecationWarning: The anyio.abc.BlockingPortal alias is deprecated, use anyio.from_thread.BlockingPortal instead.
_PortalFactoryType = Callable[[], AbstractContextManager[anyio.abc.BlockingPortal]]
-- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html
!!!!!!!!!!!!!!!!!!!!!!!!!! stopping after 1 failures !!!!!!!!!!!!!!!!!!!!!!!!!!!
1 failed, 1 warning in 0.60s