• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

hardbyte / python-can / 11256605622

09 Oct 2024 02:02PM UTC coverage: 70.371% (-0.1%) from 70.515%
11256605622

Pull #1870

github

web-flow
Merge 907b1d795 into 7a3d23fa3
Pull Request #1870: Add tox environment for doctest

7472 of 10618 relevant lines covered (70.37%)

15.42 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

92.86
/can/exceptions.py
1
"""
24✔
2
There are several specific :class:`Exception` classes to allow user
3
code to react to specific scenarios related to CAN busses::
4

5
    Exception (Python standard library)
6
     +-- ...
7
     +-- CanError (python-can)
8
         +-- CanInterfaceNotImplementedError
9
         +-- CanInitializationError
10
         +-- CanOperationError
11
         +-- CanTimeoutError
12

13
Keep in mind that some functions and methods may raise different exceptions.
14
For example, validating typical arguments and parameters might result in a
15
:class:`ValueError`. This should always be documented for the function at hand.
16
"""
17

18
import sys
24✔
19
from contextlib import contextmanager
24✔
20
from typing import Optional, Type
24✔
21

22
if sys.version_info >= (3, 9):
24✔
23
    from collections.abc import Generator
24✔
24
else:
25
    from typing import Generator
×
26

27

28
class CanError(Exception):
24✔
29
    """Base class for all CAN related exceptions.
24✔
30

31
    If specified, the error code is automatically appended to the message:
32

33
    .. testsetup:: canerror
34

35
        from can import CanError, CanOperationError
36

37
    .. doctest:: canerror
38

39
        >>> # With an error code (it also works with a specific error):
40
        >>> error = CanOperationError(message="Failed to do the thing", error_code=42)
41
        >>> str(error)
42
        'Failed to do the thing [Error Code 42]'
43
        >>>
44
        >>> # Missing the error code:
45
        >>> plain_error = CanError(message="Something went wrong ...")
46
        >>> str(plain_error)
47
        'Something went wrong ...'
48

49
    :param error_code:
50
        An optional error code to narrow down the cause of the fault
51

52
    :arg error_code:
53
        An optional error code to narrow down the cause of the fault
54
    """
55

56
    def __init__(
24✔
57
        self,
58
        message: str = "",
59
        error_code: Optional[int] = None,
60
    ) -> None:
61
        self.error_code = error_code
24✔
62
        super().__init__(
24✔
63
            message if error_code is None else f"{message} [Error Code {error_code}]"
64
        )
65

66

67
class CanInterfaceNotImplementedError(CanError, NotImplementedError):
24✔
68
    """Indicates that the interface is not supported on the current platform.
24✔
69

70
    Example scenarios:
71
      - No interface with that name exists
72
      - The interface is unsupported on the current operating system or interpreter
73
      - The driver could not be found or has the wrong version
74
    """
75

76

77
class CanInitializationError(CanError):
24✔
78
    """Indicates an error the occurred while initializing a :class:`can.BusABC`.
24✔
79

80
    If initialization fails due to a driver or platform missing/being unsupported,
81
    a :exc:`~can.exceptions.CanInterfaceNotImplementedError` is raised instead.
82
    If initialization fails due to a value being out of range, a :class:`ValueError`
83
    is raised.
84

85
    Example scenarios:
86
      - Try to open a non-existent device and/or channel
87
      - Try to use an invalid setting, which is ok by value, but not ok for the interface
88
      - The device or other resources are already used
89
    """
90

91

92
class CanOperationError(CanError):
24✔
93
    """Indicates an error while in operation.
24✔
94

95
    Example scenarios:
96
      - A call to a library function results in an unexpected return value
97
      - An invalid message was received
98
      - The driver rejected a message that was meant to be sent
99
      - Cyclic redundancy check (CRC) failed
100
      - A message remained unacknowledged
101
      - A buffer is full
102
    """
103

104

105
class CanTimeoutError(CanError, TimeoutError):
24✔
106
    """Indicates the timeout of an operation.
24✔
107

108
    Example scenarios:
109
      - Some message could not be sent after the timeout elapsed
110
      - No message was read within the given time
111
    """
112

113

114
@contextmanager
24✔
115
def error_check(
24✔
116
    error_message: Optional[str] = None,
117
    exception_type: Type[CanError] = CanOperationError,
118
) -> Generator[None, None, None]:
119
    """Catches any exceptions and turns them into the new type while preserving the stack trace."""
120
    try:
24✔
121
        yield
24✔
122
    except Exception as error:  # pylint: disable=broad-except
24✔
123
        if error_message is None:
24✔
124
            raise exception_type(str(error)) from error
×
125
        else:
126
            raise exception_type(error_message) from error
24✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc