<h1>Debugging Application Errors<aclass="headerlink"href="#debugging-application-errors"title="Link to this heading">¶</a></h1>
<sectionid="in-production">
<h2>In Production<aclass="headerlink"href="#in-production"title="Link to this heading">¶</a></h2>
<p><strong>Do not run the development server, or enable the built-in debugger, in
a production environment.</strong> 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.</p>
<p>Use an error logging tool, such as Sentry, as described in
<aclass="reference internal"href="errorhandling.html#error-logging-tools"><spanclass="std std-ref">Error Logging Tools</span></a>, or enable logging and notifications as
described in <aclass="reference internal"href="logging.html"><spanclass="doc">Logging</span></a>.</p>
<p>If you have access to the server, you could add some code to start an
external debugger if <codeclass="docutils literal notranslate"><spanclass="pre">request.remote_addr</span></code> 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.</p>
</section>
<sectionid="the-built-in-debugger">
<h2>The Built-In Debugger<aclass="headerlink"href="#the-built-in-debugger"title="Link to this heading">¶</a></h2>
<p>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.</p>
<imgalt="screenshot of debugger in action"class="screenshot align-center"src="_images/debugger.png"/>
<p>When running from Python code, passing <codeclass="docutils literal notranslate"><spanclass="pre">debug=True</span></code> enables debug mode, which is
<p><aclass="reference internal"href="server.html"><spanclass="doc">Development Server</span></a> and <aclass="reference internal"href="cli.html"><spanclass="doc">Command Line Interface</span></a> have more information about running the debugger and
debug mode. More information about the debugger can be found in the <aclass="reference external"href="https://werkzeug.palletsprojects.com/debug/">Werkzeug
<p>Disabling these isn’t required, an external debugger will continue to work with the
following caveats.</p>
<ul>
<li><p>If the built-in debugger is not disabled, it will catch unhandled exceptions before
the external debugger can.</p></li>
<li><p>If the reloader is not disabled, it could cause an unexpected reload if code changes
during a breakpoint.</p></li>
<li><p>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 <codeclass="docutils literal notranslate"><spanclass="pre">passthrough_errors=True</span></code> to <codeclass="docutils literal notranslate"><spanclass="pre">app.run</span></code>.</p>