Kotlin / kotlin-jupyter

Kotlin kernel for Jupyter/IPython
Apache License 2.0
1.1k stars 105 forks source link

Add exception handling/interception #332

Closed jbaron closed 2 years ago

jbaron commented 2 years ago

Currently there is no easy way to format how exceptions that are thrown by code are displayed in the output of the cell.

It would be good from a usability point of view to have some influence on this, since the amount of info that is typically shown (like including full stack trace) doesn't often make much sense in the context of a notebook. One example is require (IllegalArgument exceptions). These could be presented in a much nicer way with focus on the message and perhaps no stack trace at all or collapsed.

So request to add an Exception API (for example to the JupyterIntegration class) that makes possible to handle exceptions and transform them into something else.

See also a short discussion on: https://kotlinlang.slack.com/archives/C4W52CFEZ/p1631949623037000

ileasile commented 2 years ago

@jbaron please take a look at the PR and examples. Tell me if it suits you

jbaron commented 2 years ago

@ileasile

If I understand the PR correctly it is possible to add one or more ThrowableRenderers to my JupyterIntegration class that will allow me to transform the output of certain type of Exceptions before returning it to the Notebook. Like in your example only render the message and not the whole stack trace for IllegalArgument Exceptions.

That would be great and fits my use-case very well.

P.S I'm not familiar with the use of USE {} in your example. So just to be sure I don't misunderstand things, for me this is about the library author being able to decide how to present Exceptions, not the user of a Notebook. So it is not required to enter USE {} by an end user if I already take care of it using the JupyterIntegration approach. Correct?

P.P.S Thanks also for the quick solution!!!

ileasile commented 2 years ago

@jbaron Yes, you understood everything correctly. USE{} is just a way to define a library in place, inside the notebook. You can do exactly the same in your Integration class - and if you do, user should not do anything more. I've changed API a bit and made it possible to return Any from renderThrowable method to make it consistent with render() in other renderers. It is better to return DisplayResult though, other objects will be simply stringified with toString() and represented as text.

jbaron commented 2 years ago

Great, looking forward to incorporate it in my code-base. And thanks for so quickly adding this feature!