outputs icon indicating copy to clipboard operation
outputs copied to clipboard

Handling uncaught promise rejects in Jupyter widgets package

Open vivek1729 opened this issue 4 years ago • 2 comments

Hey folks, we are leveraging the @nteract/jupyter-widgets to support ipywidgets in our notebooks experience. I noticed that while rendering some notebooks that contain widget reference(s), we start seeing errors like the following on the console:

image

Cause

On a deeper investigation, the error is coming from this line in the WidgetDisplay component:

const model = await modelById(model_id);

I believe the component tries to fetch the model state from the kernel and if the state is not found there is a promise rejection that is uncaught in WidgetDisplay. This seems to be printing out this uncaught exceptions on to the console.

Proposal

I think the line I highlighted above with modelById should be surrounded by a try-catch block.

However, I wanted to understand what is the guidance on routing errors when caught? From this discussion thread, it seems like we might be able to dispatch an action so that hosts like us can then intercept these actions in our own epics if we need to log those errors upstream. However, I couldn't locate which action should we be relying on. Would you be able to provide some guidance here?

Thanks!

vivek1729 avatar Sep 01 '21 20:09 vivek1729

Ah, this is an interesting one.

Instead of retroactively catching the exceptions and trying to log, can we be defensive and check for some required state before trying to get the model by the ideal. For example, we can try to make this selector:

https://github.com/nteract/outputs/blob/313144d1058c38c6802057eddea1ba204d9fee7a/packages/jupyter-widgets/src/index.tsx#L89

A little more resilient.

I'm proposing this because the logging question opens up a can of worms that is still unresolved as mentioned above.

captainsafia avatar Sep 02 '21 02:09 captainsafia

The failure seems to be happening in the following section where we try to request some state from the kernel:

https://github.com/nteract/outputs/blob/313144d1058c38c6802057eddea1ba204d9fee7a/packages/jupyter-widgets/src/index.tsx#L92-L95

Looking at the code comment, the request from kernel seems to be a fallback when we are unable to find the model state in the redux store. The selector already has returned null, I am not sure if there is any other info in the redux state which would help us avoid the kernel request check. I am not too familiar with the widget protocol so I don't fully understand the intent behind requesting the state from kernel when model couldn't be find in redux state.

We can potentially check for failure in this section and return null when the kernel is unable to find the model state. This way the modelById method won't throw an exception as we would cover both the success and failure case.

vivek1729 avatar Sep 03 '21 01:09 vivek1729