You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
š Fix unhandled growing memory for internal server errors, refactor dependencies with yield and except to require raising again as in regular Python (#11191)
Copy file name to clipboardExpand all lines: docs/en/docs/tutorial/dependencies/dependencies-with-yield.md
+67-3Lines changed: 67 additions & 3 deletions
Original file line number
Diff line number
Diff line change
@@ -162,6 +162,63 @@ The same way, you could raise an `HTTPException` or similar in the exit code, af
162
162
163
163
An alternative you could use to catch exceptions (and possibly also raise another `HTTPException`) is to create a [Custom Exception Handler](../handling-errors.md#install-custom-exception-handlers){.internal-link target=_blank}.
164
164
165
+
## Dependencies with `yield` and `except`
166
+
167
+
If you catch an exception using `except` in a dependency with `yield` and you don't raise it again (or raise a new exception), FastAPI won't be able to notice there was an exception, the same way that would happen with regular Python:
In this case, the client will see an *HTTP 500 Internal Server Error* response as it should, given that we are not raising an `HTTPException` or similar, but the server will **not have any logs** or any other indication of what was the error. š±
191
+
192
+
### Always `raise` in Dependencies with `yield` and `except`
193
+
194
+
If you catch an exception in a dependency with `yield`, unless you are raising another `HTTPException` or similar, you should re-raise the original exception.
195
+
196
+
You can re-raise the same exception using `raise`:
Now the client will get the same *HTTP 500 Internal Server Error* response, but the server will have our custom `InternalError` in the logs. š
221
+
165
222
## Execution of dependencies with `yield`
166
223
167
224
The sequence of execution is more or less like this diagram. Time flows from top to bottom. And each column is one of the parts interacting or executing code.
@@ -187,7 +244,6 @@ participant tasks as Background tasks
dep -->> dep: Can catch exception, raise a new HTTPException, raise other exception
190
-
dep -->> handler: Auto forward exception
191
247
end
192
248
handler -->> client: HTTP error response
193
249
end
@@ -210,15 +266,23 @@ participant tasks as Background tasks
210
266
!!! tip
211
267
This diagram shows `HTTPException`, but you could also raise any other exception that you catch in a dependency with `yield` or with a [Custom Exception Handler](../handling-errors.md#install-custom-exception-handlers){.internal-link target=_blank}.
212
268
213
-
If you raise any exception, it will be passed to the dependencies with yield, including `HTTPException`, and then **again** to the exception handlers. If there's no exception handler for that exception, it will then be handled by the default internal `ServerErrorMiddleware`, returning a 500 HTTP status code, to let the client know that there was an error in the server.
269
+
If you raise any exception, it will be passed to the dependencies with yield, including `HTTPException`. In most cases you will want to re-raise that same exception or a new one from the dependency with `yield` to make sure it's properly handled.
214
270
215
-
## Dependencies with `yield`, `HTTPException` and Background Tasks
271
+
## Dependencies with `yield`, `HTTPException`, `except` and Background Tasks
216
272
217
273
!!! warning
218
274
You most probably don't need these technical details, you can skip this section and continue below.
219
275
220
276
These details are useful mainly if you were using a version of FastAPI prior to 0.106.0 and used resources from dependencies with `yield` in background tasks.
221
277
278
+
### Dependencies with `yield` and `except`, Technical Details
279
+
280
+
Before FastAPI 0.110.0, if you used a dependency with `yield`, and then you captured an exception with `except` in that dependency, and you didn't raise the exception again, the exception would be automatically raised/forwarded to any exception handlers or the internal server error handler.
281
+
282
+
This was changed in version 0.110.0 to fix unhandled memory consumption from forwarded exceptions without a handler (internal server errors), and to make it consistent with the behavior of regular Python code.
283
+
284
+
### Background Tasks and Dependencies with `yield`, Technical Details
285
+
222
286
Before FastAPI 0.106.0, raising exceptions after `yield` was not possible, the exit code in dependencies with `yield` was executed *after* the response was sent, so [Exception Handlers](../handling-errors.md#install-custom-exception-handlers){.internal-link target=_blank} would have already run.
223
287
224
288
This was designed this way mainly to allow using the same objects "yielded" by dependencies inside of background tasks, because the exit code would be executed after the background tasks were finished.
0 commit comments