Raise two errors at the same time

后端 未结 6 1191
一个人的身影
一个人的身影 2021-02-19 03:10

Is there any way to raise two errors at the same time by using try and except? For example, ValueError and KeyError.

How do I do that?

相关标签:
6条回答
  • 2021-02-19 03:35

    You can Raise more than one exception like this:

    try:
        i = 0
        j = 1 / i
    except ZeroDivisionError:
        try:
            i = 'j'
            j = 4 + i
        except TypeError:
            raise ValueError
    

    NOTE: it may be that only the ValueError is raised but this error message seems right:

    Traceback (most recent call last):
      File "<pyshell#9>", line 3, in <module>
        j = 1 / i
    ZeroDivisionError: division by zero
    
    During handling of the above exception, another exception occurred:
    
    Traceback (most recent call last):
      File "<pyshell#9>", line 7, in <module>
        j = 4 + i
    TypeError: unsupported operand type(s) for +: 'int' and 'str'
    
    During handling of the above exception, another exception occurred:
    
    Traceback (most recent call last):
      File "<pyshell#9>", line 9, in <module>
        raise ValueError
    ValueError
    
    0 讨论(0)
  • 2021-02-19 03:41

    You could raise an error which inherits from both ValueError and KeyError. It would get caught by a catch block for either.

    class MyError(ValueError, KeyError):
        ...
    
    0 讨论(0)
  • 2021-02-19 03:48

    Yes, you can handle more than one error, either using

    try:
        # your code here
    except (ValueError, KeyError) as e:
        # catch it, the exception is accessable via the variable e
    

    Or, directly add two "ways" of handling different errors:

    try:
        # your code here
    except ValueError as e:
        # catch it, the exception is accessable via the variable e
    except KeyError as e:
        # catch it, the exception is accessable via the variable e
    

    You may also leave out the "e" variable.

    Checkout the documentation: http://docs.python.org/tutorial/errors.html#handling-exceptions

    0 讨论(0)
  • 2021-02-19 03:50

    The solution from @shrewmouse still requires to choose an exception class to wrap the caught exceptions.

    • Following solution uses Exception Chaining via finally to execute code after one exception occurs
    • We don't need to know beforehand, what exceptions occur
    • Note that only the first exception that occurs can be detected from the caller via except
      • if this is a problem, use @Collin's solution above to inherit from all collected exceptions
    • You'll see the exceptions separated by:
      "During handling of the above exception, another exception occurred:"
    def raise_multiple(errors):
        if not errors:  # list emptied, recursion ends
            return
        try:
            raise errors.pop()  # pop removes list entries
        finally:
            raise_multiple(errors)  # recursion
    

    If you have a task that needs to be done for each element of a list, you don't need to collect the Exceptions beforehand. Here's an example for multiple file deletion with multiple error reporting:

    def delete_multiple(files):
        if not files:
            return
        try:
            os.remove(files.pop())
        finally:
            delete_multiple(files)
    

    PS:
    Tested with Python 3.8.5
    To print full traceback per exception have a look at traceback.print_exc
    The original question is answered since years. But as this page is the top search result for "python raise multiple" I share my approach to fill an (IMHO relevant) gap in the solution spectrum.

    0 讨论(0)
  • 2021-02-19 03:52

    The question asks how to RAISE multiple errors not catch multiple errors.

    Strictly speaking you can't raise multiple exceptions but you could raise an object that contains multiple exceptions.

    raise Exception(
        [
            Exception("bad"),
            Exception("really bad"),
            Exception("really really bad"),
        ]
    )
    

    Question: Why would you ever want to do this?
    Answer: In a loop when you want to raise an error but process the loop to completion.

    For example when unit-testing with unittest2 you might want to raise an exception and keep processing then raise all of the errors at the end. This way you can see all of the errors at once.

    def test_me(self):
    
        errors = []
    
        for modulation in self.modulations:
            logging.info('Testing modulation = {modulation}'.format(**locals()))
    
            self.digitalModulation().set('value', modulation)
            reply = self.getReply()
    
            try: 
                self._test_nodeValue(reply, self.digitalModulation())
            except Exception as e:
                errors.append(e)
    
        if errors:
            raise Exception(errors)
    
    0 讨论(0)
  • 2021-02-19 03:53
    try :
        pass
    except (ValueError,KeyError):
        pass
    

    read more about Handling exceptions

    0 讨论(0)
提交回复
热议问题