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.

1 Like

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.

1 Like

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(...)