Repository: plotly/dash
File: dash/_callback.py (Python)

Code before:
                if progress_outputs:
                    # Get the progress before the result as it would be erased after the results.
                    progress = callback_manager.get_progress(cache_key)
                    if progress:
                        response["progress"] = {
                            str(x): progress[i] for i, x in enumerate(progress_outputs)
                        }

                output_value = callback_manager.get_result(cache_key, job_id)
                # Must get job_running after get_result since get_results terminates it.
                job_running = callback_manager.job_running(job_id)
                if not job_running and output_value is callback_manager.UNDEFINED:
                    # Job canceled -> no output to close the loop.
                    output_value = NoUpdate()

                elif (
                    isinstance(output_value, dict)
                    and "long_callback_error" in output_value
                ):
                    error = output_value.get("long_callback_error", {})
                    exc = LongCallbackError(
                        f"An error occurred inside a long callback: {error['msg']}\n{error['tb']}"
                    )
                    if error_handler:
                        error_handler(exc)
                        output_value = NoUpdate()
                        # set_props from the error handler uses the original ctx
                        # instead of manager.get_updated_props since it runs in the
                        # request process.
                        has_update = _set_side_update(callback_ctx, response)
                    else:
                        raise exc

                if job_running and output_value is not callback_manager.UNDEFINED:
                    # cached results.
                    callback_manager.terminate_job(job_id)

                if multi and isinstance(output_value, (list, tuple)):
                    output_value = [
                        NoUpdate() if NoUpdate.is_no_update(r) else r
                        for r in output_value
                    ]
                updated_props = callback_manager.get_updated_props(cache_key)
                if len(updated_props) > 0:
                    response["sideUpdate"] = updated_props
                    has_update = True

                if output_value is callback_manager.UNDEFINED:
                    return to_json(response)
            else:
                try:

Review comment (suggestion):
see https://github.com/plotly/dash/pull/2903/files#r1669336763

```suggestion
                        output_value = error_handler(exc)
                        output_value = output_value or NoUpdate()
```

Code after:
                if progress_outputs:
                    # Get the progress before the result as it would be erased after the results.
                    progress = callback_manager.get_progress(cache_key)
                    if progress:
                        response["progress"] = {
                            str(x): progress[i] for i, x in enumerate(progress_outputs)
                        }

                output_value = callback_manager.get_result(cache_key, job_id)
                # Must get job_running after get_result since get_results terminates it.
                job_running = callback_manager.job_running(job_id)
                if not job_running and output_value is callback_manager.UNDEFINED:
                    # Job canceled -> no output to close the loop.
                    output_value = NoUpdate()

                elif (
                    isinstance(output_value, dict)
                    and "long_callback_error" in output_value
                ):
                    error = output_value.get("long_callback_error", {})
                    exc = LongCallbackError(
                        f"An error occurred inside a long callback: {error['msg']}\n{error['tb']}"
                    )
                    if error_handler:
                        output_value = error_handler(exc)

                        if output_value is None:
                            output_value = NoUpdate()
                        # set_props from the error handler uses the original ctx
                        # instead of manager.get_updated_props since it runs in the
                        # request process.
                        has_update = (
                            _set_side_update(callback_ctx, response)
                            or output_value is not None
                        )
                    else:
                        raise exc

                if job_running and output_value is not callback_manager.UNDEFINED:
                    # cached results.
                    callback_manager.terminate_job(job_id)

                if multi and isinstance(output_value, (list, tuple)):
                    output_value = [
                        NoUpdate() if NoUpdate.is_no_update(r) else r
                        for r in output_value
                    ]
                updated_props = callback_manager.get_updated_props(cache_key)
                if len(updated_props) > 0:
                    response["sideUpdate"] = updated_props
                    has_update = True