turn on traceback filtering raw keras tracebacks also known as stack traces involve many internal frames which can be challenging to read through while not being actionable for end users by default keras filters internal frames in most exceptions that it raises to keep traceback short readable and focused on what s actionable for you your own code see also keras config disabletracebackfiltering and keras config istracebackfilteringenabled if you have previously disabled traceback filtering via keras config disabletracebackfiltering you can reenable it via keras config enabletracebackfiltering turn off traceback filtering raw keras tracebacks also known as stack traces involve many internal frames which can be challenging to read through while not being actionable for end users by default keras filters internal frames in most exceptions that it raises to keep traceback short readable and focused on what s actionable for you your own code see also keras config enabletracebackfiltering and keras config istracebackfilteringenabled if you have previously disabled traceback filtering via keras config disabletracebackfiltering you can reenable it via keras config enabletracebackfiltering check if traceback filtering is enabled raw keras tracebacks also known as stack traces involve many internal frames which can be challenging to read through while not being actionable for end users by default keras filters internal frames in most exceptions that it raises to keep traceback short readable and focused on what s actionable for you your own code see also keras config enabletracebackfiltering and keras config disabletracebackfiltering if you have previously disabled traceback filtering via keras config disabletracebackfiltering you can reenable it via keras config enabletracebackfiltering returns boolean true if traceback filtering is enabled and false otherwise iterate through traceback frames and return a new filtered traceback lasttb none tblist listtraceback walktbtb for f lineno in reversedtblist if includeframef fcode cofilename lasttb types tracebacktypelasttb f f flasti lineno if lasttb is none and tblist if no frames were kept during filtering create a new traceback from the outermost function f lineno tblist1 lasttb types tracebacktypelasttb f f flasti lineno return lasttb def filtertracebackfn to get the full stack trace call keras config disabletracebackfiltering add information about call argument values to an error message arguments fn function to wrap exceptions raised by the this function will be reraised with additional information added to the error message displaying the values of the different arguments that the function was called with objectname string display name of the classfunction being called e g layer layername layerclass returns a wrapped version of fn only inject info for the innermost failing call the first argument is self so filter it out likely unbindable arguments add argument context get original error message and append information to it canonically the 1st argument in an exception is the error message this works for all builtin python exceptions reraise exception with added context for standard exceptions such as valueerror typeerror etc for any custom error that doesn t have a standard signature simplified representation for eager graph tensors to keep messages readable turn on traceback filtering raw keras tracebacks also known as stack traces involve many internal frames which can be challenging to read through while not being actionable for end users by default keras filters internal frames in most exceptions that it raises to keep traceback short readable and focused on what s actionable for you your own code see also keras config disable_traceback_filtering and keras config is_traceback_filtering_enabled if you have previously disabled traceback filtering via keras config disable_traceback_filtering you can re enable it via keras config enable_traceback_filtering turn off traceback filtering raw keras tracebacks also known as stack traces involve many internal frames which can be challenging to read through while not being actionable for end users by default keras filters internal frames in most exceptions that it raises to keep traceback short readable and focused on what s actionable for you your own code see also keras config enable_traceback_filtering and keras config is_traceback_filtering_enabled if you have previously disabled traceback filtering via keras config disable_traceback_filtering you can re enable it via keras config enable_traceback_filtering check if traceback filtering is enabled raw keras tracebacks also known as stack traces involve many internal frames which can be challenging to read through while not being actionable for end users by default keras filters internal frames in most exceptions that it raises to keep traceback short readable and focused on what s actionable for you your own code see also keras config enable_traceback_filtering and keras config disable_traceback_filtering if you have previously disabled traceback filtering via keras config disable_traceback_filtering you can re enable it via keras config enable_traceback_filtering returns boolean true if traceback filtering is enabled and false otherwise iterate through traceback frames and return a new filtered traceback if no frames were kept during filtering create a new traceback from the outermost function filter out keras internal traceback frames in exceptions raised by fn to get the full stack trace call keras config disable_traceback_filtering add information about call argument values to an error message arguments fn function to wrap exceptions raised by the this function will be re raised with additional information added to the error message displaying the values of the different arguments that the function was called with object_name string display name of the class function being called e g layer layer_name layerclass returns a wrapped version of fn only inject info for the innermost failing call the first argument is self so filter it out likely unbindable arguments add argument context get original error message and append information to it canonically the 1st argument in an exception is the error message this works for all built in python exceptions reraise exception with added context for standard exceptions such as valueerror typeerror etc for any custom error that doesn t have a standard signature simplified representation for eager graph tensors to keep messages readable
import inspect
import os
import traceback
import types
from functools import wraps

import tree

from keras import backend
from keras.api_export import keras_export
from keras.backend.common import global_state

_EXCLUDED_PATHS = (
    os.path.abspath(os.path.join(__file__, "..", "..")),
    os.path.join("tensorflow", "python"),
)


@keras_export("keras.config.enable_traceback_filtering")
def enable_traceback_filtering():
    
    global_state.set_global_attribute("traceback_filtering", True)


@keras_export("keras.config.disable_traceback_filtering")
def disable_traceback_filtering():
    
    global_state.set_global_attribute("traceback_filtering", False)


@keras_export("keras.config.is_traceback_filtering_enabled")
def is_traceback_filtering_enabled():
    
    return global_state.get_global_attribute("traceback_filtering", True)


def include_frame(fname):
    for exclusion in _EXCLUDED_PATHS:
        if exclusion in fname:
            return False
    return True


def _process_traceback_frames(tb):
    
    last_tb = None
    tb_list = list(traceback.walk_tb(tb))
    for f, line_no in reversed(tb_list):
        if include_frame(f.f_code.co_filename):
            last_tb = types.TracebackType(last_tb, f, f.f_lasti, line_no)
    if last_tb is None and tb_list:
        
        
        f, line_no = tb_list[-1]
        last_tb = types.TracebackType(last_tb, f, f.f_lasti, line_no)
    return last_tb


def filter_traceback(fn):
    

    @wraps(fn)
    def error_handler(*args, **kwargs):
        if not is_traceback_filtering_enabled():
            return fn(*args, **kwargs)

        filtered_tb = None
        try:
            return fn(*args, **kwargs)
        except Exception as e:
            filtered_tb = _process_traceback_frames(e.__traceback__)
            
            
            raise e.with_traceback(filtered_tb) from None
        finally:
            del filtered_tb

    return error_handler


def inject_argument_info_in_traceback(fn, object_name=None):
    
    if backend.backend() == "tensorflow":
        from tensorflow import errors as tf_errors
    else:
        tf_errors = None

    @wraps(fn)
    def error_handler(*args, **kwargs):
        if not is_traceback_filtering_enabled():
            return fn(*args, **kwargs)

        signature = None
        bound_signature = None
        try:
            return fn(*args, **kwargs)
        except Exception as e:
            if hasattr(e, "_keras_call_info_injected"):
                
                raise e
            signature = inspect.signature(fn)
            try:
                
                bound_signature = signature.bind(*args, **kwargs)
            except TypeError:
                
                raise e

            
            arguments_context = []
            for arg in list(signature.parameters.values()):
                if arg.name in bound_signature.arguments:
                    value = tree.map_structure(
                        format_argument_value,
                        bound_signature.arguments[arg.name],
                    )
                else:
                    value = arg.default
                arguments_context.append(f"  • {arg.name}={value}")
            if arguments_context:
                arguments_context = "\n".join(arguments_context)
                
                if tf_errors is not None and isinstance(e, tf_errors.OpError):
                    message = e.message
                elif e.args:
                    
                    
                    message = e.args[0]
                else:
                    message = ""
                display_name = f"{object_name if object_name else fn.__name__}"
                message = (
                    f"Exception encountered when calling {display_name}.\n\n"
                    f"\x1b[1m{message}\x1b[0m\n\n"
                    f"Arguments received by {display_name}:\n"
                    f"{arguments_context}"
                )

                
                if tf_errors is not None and isinstance(e, tf_errors.OpError):
                    new_e = e.__class__(e.node_def, e.op, message, e.error_code)
                else:
                    try:
                        
                        
                        new_e = e.__class__(message)
                    except TypeError:
                        
                        
                        new_e = RuntimeError(message)
                new_e._keras_call_info_injected = True
            else:
                new_e = e
            raise new_e.with_traceback(e.__traceback__) from None
        finally:
            del signature
            del bound_signature

    return error_handler


def format_argument_value(value):
    if backend.is_tensor(value):
        
        
        if backend.backend() == "tensorflow":
            tensor_cls = "tf.Tensor"
        elif backend.backend() == "jax":
            tensor_cls = "jnp.ndarray"
        elif backend.backend() == "torch":
            tensor_cls = "torch.Tensor"
        elif backend.backend() == "numpy":
            tensor_cls = "np.ndarray"
        else:
            tensor_cls = "array"

        return (
            f"{tensor_cls}(shape={value.shape}, "
            f"dtype={backend.standardize_dtype(value.dtype)})"
        )
    return repr(value)