InternalServerError handling in flask/dash

I’m trying to achieve the same as done here: http status code 404 - How to create 404 error page in Dash (plotly)? - Stack Overflow
and here: How to create 404 error page in Dash? - #7 by cufflink

with:

from flask import Flask, render_template, redirect
from dash.dependencies import Input, Output
from dash import Dash, html
import dash_bootstrap_components as dbc
from werkzeug.exceptions import InternalServerError


server = Flask(__name__)
app = Dash(__name__, server=server)
app.layout = html.Div([
    dbc.Button('make error', id='make-error')
    ])


@app.callback(Output('make-error', 'children'),
              Input('make-error', 'n_clicks'), prevent_initial_call=True)
def make_error(n):
    if n:
        raise InternalServerError
    return 'error made'


@server.errorhandler(InternalServerError)
def make_error(error):
    print('error made')
    return render_template("error.html", title="InternalServerError")


if __name__ == "__main__":
    server.run()

But it does not work as expected. What am I missing? :smiley:

Hi @luggie,

any updates on this? Did you make it work?

I am looking to the same

Thanks

Hello @VictorCallejas,

Welcome to the forums.

So, for adding stuff to the flask server, you need to add all your specialized route before you initialize dash.

Hi @jinnyzor thanks for the welcome :smile:

(Dash 2.7)
I made it work like this, so I don’t think that is needed:

app = Dash()

@app.server.errorhandler(HTTPException)
def handle_http_exception(e):
    METRICS_APP_HTTP_ERROR_COUNTER.inc()
    dialog_err = f'HTTP EXCEPTION HANDLER - code={e.code}, name={e.name}, description={e.description}'
    logging.error(dialog_err)
    return render_template("exception.html", code=e.code, name=e.name, description=e.description, url_redirect=f"http://{URL_BASE + URL_BASE_PATHNAME}")


@app.server.errorhandler(InternalServerError)
def handle_internal_server_error(e):
    METRICS_APP_INTERNAL_SERVER_ERROR_COUNTER.inc()
    dialog_err = f'INTERNAL SERVER ERROR - code={e.code}, name={e.name}, description={e.description}'
    logging.error(dialog_err)
    return render_template("exception.html", code=e.code, name=e.name, description=e.description, url_redirect=f"http://{URL_BASE + URL_BASE_PATHNAME}")

I was interested in the modal thing. So instead of showing the typical 404-500 template, when a runtime error happens just showing a modal dialog but it always redirects to the error default template.

Nice, as long as it’s working as expected. :stuck_out_tongue_winking_eye:

I add the server and add a bunch of routing in my own use.

Also, someone else’s issue was a redirect wasn’t firing properly, so had to bring it in front of the dash initialization because the routings were fighting with each other.

Does not work for me.
Where do you place your templates?

As as minimal example, would it also work with:

@app.server.errorhandler(HTTPException)
def handle_http_exception(e):
    return render_template("test.html")


@app.server.errorhandler(InternalServerError)
def handle_internal_server_error(e):
    return render_template("test.html")

Hello @luggie,

Normally for Flask, your templates go in a folder called templates. Just like pages and assets.

this does not seem to work when working with a multipage dash app.
For example, if I want to add a custom 404 page and try to catch flask errors with errorhandler, even with errorhandler(404), the handler is not triggered :frowning:

How is your app.py setup?

It should work, try to add some logging statements in the function, maybe is being triggered but is the render_template that fails.

render_tempalte is from flask and will look for a “templates” folder, I have it at the same level than the app.py/index.py

my setup is:

app = Dash(...)

@app.server.errorhandler(HTTPException)
def handle_http_exception(e):
    ...

app.run_server(...)