-
Notifications
You must be signed in to change notification settings - Fork 64
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix parsing tests and line start matching #132
Conversation
There was a reason we catch the parse exception and only log it. If this is solely for testing then we need to find another test strategy. (Basically this is undoing pull request #74 ) |
Maybe the TelegramParser should raise an error and the clients like serialreader should determine what to do with it? So move the error logging to all clients? |
The question here is: is it a good idea to just ignore parsing errors and don't pass anything to the application using the dsmr_parser lib? PR #74 might be the wrong solution? The application that calls the .parse() function should handle the exception imo. But that's just my opinion :) |
Just rebased :) |
The question is: if a single line does not parse, does that render all other lines invalid? The answer is no, as we saw in the practical examples. As the exception breaks the parsing loop, once the exception is propagated upwards there is no chance to know what the other lines parse into. So I still think that #74 is an elegant solution to make the parser more robust for flawed equipment out there. Maybe we can control the behaviour with a flag, like we do for CRC checksum_support? It satisifies both use cases and we do not need extensive changes on the client side. |
@@ -96,6 +96,7 @@ def parse(self, telegram_data, encryption_key="", authentication_key=""): # noq | |||
except Exception: | |||
logger.error("ignore line with signature {}, because parsing failed.".format(signature), | |||
exc_info=True) | |||
raise |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is ok, but only if all the clients that use the TelegramParser will handle the error and keep working after encountering an error. What do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Was this a reaction to my comment?
If yes, then I do not understand it, because if you would do it like i proposed, nothing changes for existing clients. The default behaviour would be to not propagate the parse exception.
0a73c94
to
93f5533
Compare
I changed the code a bit. This is what we then use in the tests to make sure everything is parsed correctly. While I still think the best way would be to let the application that uses dsmr_parser to handle the exception, you might want (like @lowdef mentioned) the parsing to continue to just ignore the failed line. The cleanest way would be to have parse return the value + the possible exception/None, but then all clients/apps using dsmr_parser would need to get updated, which we won't do :) |
If its just for unit testing, why not mock the logger and verify that way?
|
Would be an option also. But maybe somebody wants to catch exceptions in its application also in the future? |
For me the current solution ( |
Yes fine with me too! |
One question @dupondje; @ndokter : Would it not be better to catch only specificly the ParseError exception, for all other exceptions need to be propagated always as we can not know how to recover from low level system exceptions for example. for match in matches:
try:
dsmr_object = parser.parse(match)
except ParseError:
logger.error("ignore line with signature {}, because parsing failed.".format(signature),
exc_info=True)
if throw_ex:
raise
except Exception as err:
logger.error(f"Unexpected {err=}, {type(err)=}")
raise
else:
telegram.add(obis_reference=signature, dsmr_object=dsmr_object) |
@lowdef : Agree! I adjusted the commit. Just made some change to the output as we nowhere use the f"" formatter but always .format() in other places in the code :) Just to keep the same everywhere. |
yes, perfect. I assumed you would clean up, it was just for illustration what i ment. |
if throw_ex: | ||
raise | ||
except Exception as err: | ||
logger.error("Unexpected {}: {}".format(type(err), err)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No need to change, but in general when using the logging module i pass the variables as arguments:
logger.error("Unexpected %s: %s", err, err)
Here is a nice blogpost about it https://www.palkeo.com/en/blog/python-logging.html#use-a-format-string-with-arguments
In short: when doing things with the logs (for example Sentry), it allows for better grouping etc
Thanks everyone for your work, i merged it and will make a new release soon |
Interesting, didn't know that. Thanks for sharing.
Nigel Dokter ***@***.***> schrieb am Fr., 14. Apr. 2023,
16:49:
… ***@***.**** commented on this pull request.
------------------------------
In dsmr_parser/parsers.py
<#132 (comment)>:
> logger.error("ignore line with signature {}, because parsing failed.".format(signature),
exc_info=True)
+ if throw_ex:
+ raise
+ except Exception as err:
+ logger.error("Unexpected {}: {}".format(type(err), err))
No need to change, but in general when using the logging module i pass the
variables as arguments:
logger.error("Unexpected %s: %s", err, err)
Here is a nice blogpost about it
https://www.palkeo.com/en/blog/python-logging.html#use-a-format-string-with-arguments
In short: when doing things with the logs (for example Sentry), it allows
for better grouping etc
—
Reply to this email directly, view it on GitHub
<#132 (review)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/ACCJDWAIQNQ5D6NTRAL7JRDXBFPZNANCNFSM6AAAAAAW3J7P2M>
.
You are receiving this because you were mentioned.Message ID:
***@***.***>
|
@ndokter : Any chance to push a release soon? :) |
Thank you for the reminder. I pushed it under v1.2.3! https://pypi.org/project/dsmr-parser/ |
This pull req fixes 2 things:
First of all we seem to handle the exception in the code for parsing errors and just log a message.
So tests never see parsing errors. Which is not what we want :) So we raise the exception triggered by the parsing.
Next to that, we enable multiline flag on the regex, so it creates a new line after every \n.
This allows us to use line start (^) in the regexes, so we don't match things in a middle somewhere. (Fixes #128)