Search code examples
pythonexceptionreprcontrol-characters

Python raising exception where message has carriage return \r control character


I am performing serial communications with an electronic device, and the end of a response message is dictated by a carriage return (\r). If the response is garbled, I raise a custom exception. I would like my exception message to show the raw response, which may include a carriage return.

I noticed that carriage returns sort of messes up printing/representation of Python's exceptions.

Is there any way to have Python's exceptions use something like repr?


Potential Workaround

I could make a custom exception class and override some behavior to replace \r with "CR", but I am unsure if there is a simpler way.

I am also unsure which dunder methods to use, nor where to find which dunder methods to use.


What I Am Seeing

Input:

class SerError(Exception):
    """Serial communications error."""


some_msg = f"some_serial\rmessage."
print(f"some_msg = {some_msg}.\nrepr(some_msg) = {repr(some_msg)}.")
raise SerError(some_msg)

Output:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
message..SerError: some_serial

You can see Python is interpreting the control character \r by resetting the cursor to the beginning of the line, where it prints the remainder of the message.

I do not like this behavior, as it overwrites my exception message, as opposed to printing the original message.


Solution

  • Since you are defining a custom exception, you can override the __str__() method to have it return the repr that you want:

    class SerError(Exception):
        """Serial communications error."""
        def __str__(self):
            return repr(self.args[0])
    

    The self.args[0] selects only the first element of the tuple, otherwise it would return the repr of a tuple with one or more arguments.