From e55386dffd03a0a46f2618e4065127e79a909107 Mon Sep 17 00:00:00 2001 From: Brent Barbachem Date: Mon, 11 Jul 2022 10:34:09 -0400 Subject: [PATCH] NMEASentence/__getattr__: Graceful fail ** Return None and handle the error without raising an error. Technically raising an error after catching another is bad as it still creates a stack trace (causing a hard failure) and it demolishes the original stack. Here the return None is handled and a message is logged in debug format. The other way to resolve this on a hard failure is to reraise the origin after logging just call raise to preserve the stack. ** Altered the test that utilized this code. --- pynmea2/nmea.py | 14 ++++++++++---- test/test_pynmea.py | 3 +-- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/pynmea2/nmea.py b/pynmea2/nmea.py index a7c13d0..2398042 100644 --- a/pynmea2/nmea.py +++ b/pynmea2/nmea.py @@ -1,6 +1,10 @@ import re import operator from functools import reduce +from logging import getLogger + + +log = getLogger() class ParseError(ValueError): @@ -149,10 +153,12 @@ def parse(line, check=False): def __getattr__(self, name): #pylint: disable=invalid-name t = type(self) - try: - i = t.name_to_idx[name] - except KeyError: - raise AttributeError(name) + + if name not in t.name_to_idx: + log.debug("%s has no attribute %s", self.__class__.__name__, name) + return None + i = t.name_to_idx[name] + f = t.fields[i] if i < len(self.data): v = self.data[i] diff --git a/test/test_pynmea.py b/test/test_pynmea.py index b1867c6..317f189 100644 --- a/test/test_pynmea.py +++ b/test/test_pynmea.py @@ -25,8 +25,7 @@ def test_checksum(): def test_attribute(): msg = pynmea2.parse(data) - with pytest.raises(AttributeError): - msg.foobar + assert msg.foobar is None def test_fail():