I’ve seen a few people indicate displeasure at the current method of aborting callback execution without returning a response to the client – which is to raise any exception you like in the callback.
The only reason I find this a little strategy a little frustrating is that it pollutes the terminal running the Dash app with an angry looking traceback that I think is a problem every time I see it, only to then see that it was expected.
An improvement on this situation that occurred to me is defining a special exception for halting callbacks and then having Flask catch this exception printing a quieter indication of the event then and returning an empty 204 no response.
I’ve tried this out with a test app that I’ve included below, and it seems to work, without causing the second callback which would otherwise be triggered to fire, and without causing any errors in the client. Could something like this be potentially included into Dash?
import sys
import dash
from dash.dependencies import Input, State, Output
import dash_core_components as dcc
import dash_html_components as html
app = dash.Dash()
app.layout = html.Div([
html.Div(id='target1'),
html.Div(id='target2'),
dcc.Input(id='input', type='text', value=''),
html.Button(id='submit', n_clicks=0, children='Save')
])
class HaltCallback(Exception):
pass
@app.server.errorhandler(HaltCallback)
def handle_error(error):
print(error, file=sys.stderr)
return ('', 204)
@app.callback(Output('target1', 'children'), [Input('submit', 'n_clicks')],
[State('input', 'value')])
def callback1(n_clicks, state):
raise HaltCallback("Halting because of reason foo.")
return f"callback1: {state}"
@app.callback(Output('target2', 'children'), [Input('target1', 'children')])
def callback2(value):
return f"callback2: {value}"
if __name__ == '__main__':
app.run_server(debug=True)