Skip to content

A proposed alternative to "suppress_callback_exception" #354

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
eddy-ojb opened this issue Aug 27, 2018 · 13 comments
Closed

A proposed alternative to "suppress_callback_exception" #354

eddy-ojb opened this issue Aug 27, 2018 · 13 comments

Comments

@eddy-ojb
Copy link

I use the "suppress_callback_exceptions" option a lot but think it makes sense to have an option where we can add e.g. a decorator to callbacks we care about and see why they aren't firing (.e.g "cannot see 'x' div, or 'cannot parse children of div' or w/e. I can see this being super helpful, rather than completely suppressing the exceptions and leaving the developer to guess everywhere.

@chriddyp
Copy link
Member

In principle I like this but I'm not sure technically how it would (i.e. how would we know that a callback isn't firing).

Could you walk through a couple of simple examples that demonstrate cases where callbacks wouldn't fire but we could provide better error messages?

@rmarren1
Copy link
Contributor

rmarren1 commented Aug 27, 2018

dash-renderer recently got a new feature which might help in situations where suppress_callback_exceptions covers up an error: https://github.com/plotly/dash-renderer/blob/master/CHANGELOG.md#0131---2018-07-18.

@eddy-ojb
Copy link
Author

For me, the point that @rmarren1 makes in issue 57 hits the nail on the head: "[suppressing] puts you in debugging hell for large applications".

Apologies for missing this link. I will try update my renderer and see if this helps first.

If this doesn't help, happy to make another example of where it can go wrong and what could be useful in its place. I agree with you guys where you suggest in another thread that better exception reporting is a cheap but effective solution here, rather than channeling info through javascript back to the console.

@eddy-ojb
Copy link
Author

@chriddyp shall i close the issue and move to another thread?

@rmarren1
Copy link
Contributor

That error information will be more visible in the future after plotly/dash-renderer#64 is worked through, which should functionally give you the same information as if exceptions were not suppressed.

@eddy-ojb
Copy link
Author

This actually excites me 😃. I updated my renderer to 13.1 - still some issues but can see theres a lot of work that you're done already to address this .

I think adding other exceptions to callbacks checks would be helpful too. For example, if you consider creating the following callback for a dynamic dropdown:

@app.expanded_callback(
    dash.dependencies.Output('dropdown_holder1', 'children'), 
    [dash.dependencies.Input('some-div', 'children')])
def create_dropdown1(div_value):
    
    # check if some condition met. if so create dropdown:
    dropdown  = dcc.Dropdown(
                            id='my-dropdown',
                            options=[
                                    {'label': 'New York City', 'value': 'NYC'},
                                    {'label': 'Montreal', 'value': 'MTL'},
                                    {'label': 'San Francisco', 'value': 'SF'}
                                    ],
                            value='NYC',
                            className='col-md-12',
                            ),

    return dropdown

the dropdown is a dcc, yet you have to return it as a div with children, without it being in a list.

This baffled me for ages as I was trying to return it as:
return [dropdown]

This is because it is inline with outputting a dcc in this example:

@app.expanded_callback(
    dash.dependencies.Output('graph-div', 'children'), 
    [dash.dependencies.Input('my-dropdown', 'value')])
def create_dropdown1(div_value):

    # create graph
    some_graph = dcc.Graph(..) 
    return [some_graph] `

but:
return some_graph does not work.

Is it possible to check the type of the content returned by a callback and check that it is compatible with the output type specified in the callback when in debug mode?
Alternatively, I have seen the @chriddyp solution here, which I haven;t tried yet but will give a go soon.

@rmarren1
Copy link
Contributor

Is it possible to check the type of the content returned by a callback and check that it is compatible with the output type specified in the callback when in debug mode?

We are actually working on a big PR #340 which does just that. I'm pushing changes to it currently and will have a pre-release soon, so you can subscribe to that and be one of the first to test-drive it 🙂

Also I would expect those examples above to work, do they not? If so it may be a bug we can open.

@eddy-ojb
Copy link
Author

eddy-ojb commented Aug 28, 2018

Yes it doesnt work with my current setup. Before this is opened i will update my packages and build some toy examples tomorrow to confirm its still relevant.

@chriddyp
Copy link
Member

Also I would expect those examples above to work, do they not? If so it may be a bug we can open.

Yeah, if a callback updates children, any of these return objects should work:

  • string
  • single dash Component
  • number
  • None
  • Or a list of those

@eddy-ojb
Copy link
Author

This is a bug. I've created a Gist to illustrate 2 problems. I've posted version info below to replicate the issue.

  1. If deleting the only component in the layout, no dashboard is rendered and no error message is displayed to inform the developer - this stumped me for a while.

  2. At the moment, returning a dropdown, radio button or input dcc as e.g. [dropdown] in create_dropdown1 breaks the callback process. This is inconsistent with the Graph dcc, which now returns as [graph] or graph. I tried only with these 4 components.

@rmarren1 have subscribed to #340 and happy to test drive the new updates.

The Dash versions to replicate the above are currently inline with official installation versions:

pip install dash==0.26.2  # The core dash backend
pip install dash-renderer==0.13.1  # The dash front-end
pip install dash-html-components==0.11.0  # HTML components
pip install dash-core-components==0.28.0  # Supercharged components
pip install plotly==3.1.1
pip install numpy

@rmarren1
Copy link
Contributor

Check line 51 of the gist, you end have dcc.Dropdown(...),. When you end with a comma like that, python casts this to the tuple (dcc.Dropdown(...),) which is not valid.

This is a tough error to debug though, as it silently fails and just says component.type is undefined as a front-end exception, and is a good example of a case where #340 can save a lot of headaches.

@eddy-ojb
Copy link
Author

Good spot! and thanks!

Actually, to hammer home the importance of your work on #340, I did spot it was a tuple but forgot about it trying to solve error 1.

HammadTheOne pushed a commit to HammadTheOne/dash that referenced this issue May 28, 2021
- turn on strictPropertyInitialization
- turn on strictBindCallApply
HammadTheOne pushed a commit that referenced this issue Jul 23, 2021
- turn on strictPropertyInitialization
- turn on strictBindCallApply
AnnMarieW pushed a commit to AnnMarieW/dash that referenced this issue Jan 6, 2022
@gvwilson
Copy link
Contributor

Hi - we are tidying up stale issues and PRs in Plotly's public repositories so that we can focus on things that are most important to our community. If this issue is still a concern, please add a comment letting us know what recent version of our software you've checked it with so that I can reopen it and add it to our backlog. (Please note that we will give priority to reports that include a short reproducible example.) If you'd like to submit a PR, we'd be happy to prioritize a review, and if it's a request for tech support, please post in our community forum. Thank you - @gvwilson

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants