2020-07-29 02:14:17 +08:00
|
|
|
Debugging Application Errors
|
|
|
|
============================
|
|
|
|
|
|
|
|
|
|
|
|
In Production
|
|
|
|
-------------
|
|
|
|
|
|
|
|
**Do not run the development server, or enable the built-in debugger, in
|
|
|
|
a production environment.** The debugger allows executing arbitrary
|
|
|
|
Python code from the browser. It's protected by a pin, but that should
|
|
|
|
not be relied on for security.
|
|
|
|
|
|
|
|
Use an error logging tool, such as Sentry, as described in
|
|
|
|
:ref:`error-logging-tools`, or enable logging and notifications as
|
|
|
|
described in :doc:`/logging`.
|
|
|
|
|
|
|
|
If you have access to the server, you could add some code to start an
|
|
|
|
external debugger if ``request.remote_addr`` matches your IP. Some IDE
|
|
|
|
debuggers also have a remote mode so breakpoints on the server can be
|
|
|
|
interacted with locally. Only enable a debugger temporarily.
|
|
|
|
|
|
|
|
|
|
|
|
The Built-In Debugger
|
|
|
|
---------------------
|
|
|
|
|
|
|
|
The built-in Werkzeug development server provides a debugger which shows
|
|
|
|
an interactive traceback in the browser when an unhandled error occurs
|
|
|
|
during a request. This debugger should only be used during development.
|
|
|
|
|
|
|
|
.. image:: _static/debugger.png
|
|
|
|
:align: center
|
|
|
|
:class: screenshot
|
|
|
|
:alt: screenshot of debugger in action
|
|
|
|
|
|
|
|
.. warning::
|
|
|
|
|
|
|
|
The debugger allows executing arbitrary Python code from the
|
|
|
|
browser. It is protected by a pin, but still represents a major
|
|
|
|
security risk. Do not run the development server or debugger in a
|
|
|
|
production environment.
|
|
|
|
|
2022-08-02 06:11:35 +08:00
|
|
|
The debugger is enabled by default when the development server is run in debug mode.
|
2020-07-29 02:14:17 +08:00
|
|
|
|
2022-06-18 00:26:26 +08:00
|
|
|
.. code-block:: text
|
2020-07-29 02:14:17 +08:00
|
|
|
|
2023-02-16 06:24:56 +08:00
|
|
|
$ flask --app hello run --debug
|
2020-10-16 05:08:37 +08:00
|
|
|
|
2022-08-02 06:11:35 +08:00
|
|
|
When running from Python code, passing ``debug=True`` enables debug mode, which is
|
|
|
|
mostly equivalent.
|
2020-07-29 02:14:17 +08:00
|
|
|
|
|
|
|
.. code-block:: python
|
|
|
|
|
|
|
|
app.run(debug=True)
|
|
|
|
|
2022-08-02 06:11:35 +08:00
|
|
|
:doc:`/server` and :doc:`/cli` have more information about running the debugger and
|
|
|
|
debug mode. More information about the debugger can be found in the `Werkzeug
|
|
|
|
documentation <https://werkzeug.palletsprojects.com/debug/>`__.
|
2020-07-29 02:14:17 +08:00
|
|
|
|
|
|
|
|
|
|
|
External Debuggers
|
|
|
|
------------------
|
|
|
|
|
|
|
|
External debuggers, such as those provided by IDEs, can offer a more
|
|
|
|
powerful debugging experience than the built-in debugger. They can also
|
|
|
|
be used to step through code during a request before an error is raised,
|
|
|
|
or if no error is raised. Some even have a remote mode so you can debug
|
|
|
|
code running on another machine.
|
|
|
|
|
2023-04-16 02:53:06 +08:00
|
|
|
When using an external debugger, the app should still be in debug mode, otherwise Flask
|
|
|
|
turns unhandled errors into generic 500 error pages. However, the built-in debugger and
|
|
|
|
reloader should be disabled so they don't interfere with the external debugger.
|
2020-07-29 02:14:17 +08:00
|
|
|
|
2022-06-18 00:26:26 +08:00
|
|
|
.. code-block:: text
|
2020-07-29 02:14:17 +08:00
|
|
|
|
2023-02-16 06:24:56 +08:00
|
|
|
$ flask --app hello run --debug --no-debugger --no-reload
|
2020-07-29 02:14:17 +08:00
|
|
|
|
|
|
|
When running from Python:
|
|
|
|
|
|
|
|
.. code-block:: python
|
|
|
|
|
|
|
|
app.run(debug=True, use_debugger=False, use_reloader=False)
|
|
|
|
|
2023-04-16 02:53:06 +08:00
|
|
|
Disabling these isn't required, an external debugger will continue to work with the
|
|
|
|
following caveats.
|
|
|
|
|
|
|
|
- If the built-in debugger is not disabled, it will catch unhandled exceptions before
|
|
|
|
the external debugger can.
|
|
|
|
- If the reloader is not disabled, it could cause an unexpected reload if code changes
|
|
|
|
during a breakpoint.
|
|
|
|
- The development server will still catch unhandled exceptions if the built-in
|
|
|
|
debugger is disabled, otherwise it would crash on any error. If you want that (and
|
|
|
|
usually you don't) pass ``passthrough_errors=True`` to ``app.run``.
|
|
|
|
|
|
|
|
.. code-block:: python
|
|
|
|
|
|
|
|
app.run(
|
|
|
|
debug=True, passthrough_errors=True,
|
|
|
|
use_debugger=False, use_reloader=False
|
|
|
|
)
|