code: def on_exception_report_input(func_=None, force=False, keys=None):
      def _closure_onexceptreport(func):
          if not ONEX_REPORT_INPUT and not force:
              return func
          @ignores_exc_tb(outer_wrapper=False)
          def wrp_onexceptreport(*args, **kwargs):
              try:
                  return func(*args, **kwargs)
              except Exception as ex:
                  from utool import util_str
                  print('ERROR occured! Reporting input to function')
                  if keys is not None:
                      from utool import util_inspect
                      from utool import util_list
                      from utool import util_dict
                      argspec = util_inspect.get_func_argspec(func)
                      in_kwargs_flags = [key in kwargs for key in keys]
                      kwarg_keys = util_list.compress(keys, in_kwargs_flags)
                      kwarg_vals = [kwargs.get(key) for key in kwarg_keys]
                      flags = util_list.not_list(in_kwargs_flags)
                      arg_keys = util_list.compress(keys, flags)
                      arg_idxs = [argspec.args.index(key) for key in arg_keys]
                      num_nodefault = len(argspec.args) - len(argspec.defaults)
                      default_vals = (([None] * (num_nodefault)) +
                                      list(argspec.defaults))
                      args_ = list(args) + default_vals[len(args) + 1:]
                      arg_vals = util_list.take(args_, arg_idxs)
                      requested_dict = dict(util_list.flatten(
                          [zip(kwarg_keys, kwarg_vals), zip(arg_keys, arg_vals)]))
                      print('input dict = ' + util_str.repr4(
                          util_dict.dict_subset(requested_dict, keys)))
                      pass
                  arg_strs = ', '.join([repr(util_str.truncate_str(str(arg)))
                                        for arg in args])
                  kwarg_strs = ', '.join([
                      util_str.truncate_str('%s=%r' % (key, val))
                      for key, val in six.iteritems(kwargs)])
                  msg = ('\nERROR: funcname=%r,\n * args=%s,\n * kwargs=%r\n' % (
                      meta_util_six.get_funcname(func), arg_strs, kwarg_strs))
                  msg += ' * len(args) = %r\n' % len(args)
                  msg += ' * len(kwargs) = %r\n' % len(kwargs)
                  util_dbg.printex(ex, msg, pad_stdout=True)
                  raise
          wrp_onexceptreport = preserve_sig(wrp_onexceptreport, func)
          return wrp_onexceptreport
      if func_ is None:
          return _closure_onexceptreport
      else:
          return _closure_onexceptreport(func_)