def do_ruffus_exception(ruffus_five_tuple, options, log):
    """Replace the elaborate ruffus stack trace with a user friendly
    description of the error message that occurred."""
    exit_code = None

    _task_name, _job_name, exc_name, exc_value, exc_stack = ruffus_five_tuple

    if isinstance(exc_name, type):
        # ruffus is full of mystery... sometimes (probably when the process
        # group leader is killed) exc_name is the class object of the exception,
        # rather than a str. So reach into the object and get its name.
        exc_name = exc_name.__name__

    if exc_name.startswith('ocrmypdf.exceptions.'):
        base_exc_name = exc_name.replace('ocrmypdf.exceptions.', '')
        exc_class = getattr(ocrmypdf_exceptions, base_exc_name)
        exit_code = getattr(exc_class, 'exit_code', ExitCode.other_error)
        try:
            if isinstance(exc_value, exc_class):
                exc_msg = str(exc_value)
            elif isinstance(exc_value, str):
                exc_msg = exc_value
            else:
                exc_msg = str(exc_class())
        except Exception:
            exc_msg = "Unknown"

    if exc_name in ('builtins.SystemExit', 'SystemExit'):
        match = re.search(r"\.(.+?)\)", exc_value)
        exit_code_name = match.groups()[0]
        exit_code = getattr(ExitCode, exit_code_name, 'other_error')
    elif exc_name == 'ruffus.ruffus_exceptions.MissingInputFileError':
        log.error(cleanup_ruffus_error_message(exc_value))
        exit_code = ExitCode.input_file
    elif exc_name in ('builtins.KeyboardInterrupt', 'KeyboardInterrupt'):
        # We have to print in this case because the log daemon might be toast
        print("Interrupted by user", file=sys.stderr)
        exit_code = ExitCode.ctrl_c
    elif exc_name == 'subprocess.CalledProcessError':
        # It's up to the subprocess handler to report something useful
        msg = "Error occurred while running this command:"
        log.error(msg + '\n' + exc_value)
        exit_code = ExitCode.child_process_error
    elif exc_name.startswith('ocrmypdf.exceptions.'):
        if exc_msg:
            log.error(exc_msg)
    elif exc_name == 'PIL.Image.DecompressionBombError':
        msg = cleanup_ruffus_error_message(exc_value)
        msg += (
            "\nUse the --max-image-mpixels argument to set increase the "
            "maximum number of megapixels to accept."
        )
        log.error(msg)
        exit_code = ExitCode.input_file

    if exit_code is not None:
        return exit_code

    if not options.verbose:
        log.error(exc_stack)
    return ExitCode.other_error
Replace the elaborate ruffus stack trace with a user friendly
    description of the error message that occurred.