简体   繁体   中英

how do I change what an exception does when raised?

I am making a simulated operating system for my operating systems class. One subject that was covered is interrupts, as well as errors. I am going to make a simple case:

def read_instructions():
  try:
    with open('assembly.txt', 'r') as assembly:
      for line in assembly:
        status = execute_instruction(line) # this will also raise an error if instruction is invalid
  except IOError as e:
    raise IOError(1)

Instead of getting something like [err 2] File Not Found] or something along those default python lines, I want something more like this:

def Exceptions(e):
  """ this is meant to be a 'fake' event-vector table """
  self.controller[status] = e # all exceptions will do this
  def io_exception():
    print('failed while trying to find your file')
    # some traceback and logging shenanigans here
    shutdown_system()

  def invalid_assembly():
    print('your assembly line did not follow instruction set')
    # more traceback
    shutdown_system()

  def unimplemented():
    print("you made an error I didn't catch. You've won this round.")

  return {
    1: io_exception,
    2: invalid_assembly
  }.get(e, unimplemented)()

is it possible to override where the raised exceptions go, and instead have them go here?

Exceptions bubble up until they hit an except keyword. If they make it outside of the current execution context (aka they are untrapped ), they cause Python to print a stack trace and the message contained in the error (and usually terminate the thread that happened in).

You can most certainly extend Exception or any other standard error type with your own class and use raise on them, but you can't change how the exception system works, it's part of the language specification.

So what you should do is in your 'OS', trap all of the exceptions:

try:
    run_task() # Runs an OS task
except Exception as e:
    # Do OS exception handling here. This will trap any exception thrown by a task.

And then do whatever you want with that exception.

You could even define your own base exception:

class OSBaseException(Exception):
    def __init__(self, *args, **kwargs):
        super(Exception, self).__init__(*args, **kwargs)
        # any other init here
    # An OS specific method hooks here

that you expect all your user's exceptions to extend that provides some additional hooks that your OS's trap system expects.

The Curious Course on Coroutines and Concurrency actually provides a pretty good example on doing exactly what you are trying to do.

Note that you're going to be squashing all of the stack traces, which might be annoying for 'developers' working with your OS.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM