You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
print(f'Could not write to file {path}.{file_type} (Permission denied).'
is masked by a different error that does not (necessarily) match the actual problem and is actively misleading.
Explanation:
The new error message says that the file could not be written and give a "(Permission denied)" as reason.
This is not the only case were an OSError could be thrown and may actually mask important information from the exception message below.
This message is printed to stdout and the original exception is lost.
Example:
Pydot writes to a temporary file. If this operation is not allowed or does not succeed, then the error message should reflect that and not point towards the path of the actual file (as it does now).
If Pydot does not find or cannot use graphviz then it returns an OSError instead of a FileNotFoundError, which will be caught and overwritten by the given message (it turned out the PATH Python was using was not correctly configured, but Powershell could still find it)
Both errors happened to me which took quite some time to figure out what was going on as not one but two different errors were masked.
Solution:
You should never just mask previous error messages.
More information is always good.
The simplest solution is to print out the original error message (and potentially the traceback) to stderr.
This has the disadvantage of cluttering the output and may not contain all the information a user would want but it would be enough to get someone onto the right track with fixing the underlying problem. Note: Because writing happens in a separate thread, output may interleave with other output from the main thread which makes it even less clear what happened.
Raise an exception (do not let the error pass silently).
This has the advantage of making it clear an error happened and what happened but may not always be the preferred behavior eg. if the rest of an algorithm is stopped due to an uncaught exception.
You could either
not catch the original error message (always raise)
catch only the specific error of not being able to write to the file and re-raising others. (may change if Pydot changes)
always re-raise the exception but add additional information
2.5) You could make a flag if the exception should pass silently or not (which should be the default? hard to say)
To 2):
Python support raising exceptions from a given context like so:
try:
raiseOSError("This is the original message")
exceptOSErrorase:
raiseOSError("Could not read from file...") frome
which will read as:
Traceback (most recent call last):
File "catch.py", line 5, in <module>
raise OSError("This is the original message")
OSError: This is the original message
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "catch.py", line 7, in <module>
raise OSError("Could not read from file...") from e
OSError: Could not read from file...
or (what you more likely want) to extend the existing exception like so:
try:
raiseOSError("This is the original message")
exceptOSErrorase:
e.args=e.args+ ("Could not read from file...", )
raise
which will read as:
Traceback (most recent call last):
File "catch.py", line 2, in <module>
raise OSError("This is the original message")
OSError: ('This is the original message', 'Could not read from file...')
I will solve try to solve that issue tomorrow, or in case if you already have the solution implemented, you can always open the pull request and I will merge it 👯
Ps. On the unrelated note, but just so that you do not "judge the code style" in AALpy, I know that FileHandler.py is a mess that requires a redesign
Strange. It worked for me.
How are you printing the message?
This works for me in Python3.8:
try:
try:
raiseOSError("This is the original message")
exceptOSErrorase:
e.args+= ("Could not read from file...",)
raiseexceptOSErrorase:
print(e)
Results in output: ('This is the original message', 'Could not read from file...')
For full trace:
importtracebacktry:
try:
raiseOSError("This is the original message")
exceptOSErrorase:
e.args+= ("Could not read from file...",)
raiseexceptOSErrorase:
traceback.print_exc()
Problem:
The underlying OSError in
AALpy/aalpy/utils/FileHandler.py
Line 139 in 065e9ac
Explanation:
The new error message says that the file could not be written and give a "(Permission denied)" as reason.
This is not the only case were an OSError could be thrown and may actually mask important information from the exception message below.
This message is printed to stdout and the original exception is lost.
Example:
Both errors happened to me which took quite some time to figure out what was going on as not one but two different errors were masked.
Solution:
You should never just mask previous error messages.
More information is always good.
The simplest solution is to print out the original error message (and potentially the traceback) to stderr.
This has the disadvantage of cluttering the output and may not contain all the information a user would want but it would be enough to get someone onto the right track with fixing the underlying problem.
Note: Because writing happens in a separate thread, output may interleave with other output from the main thread which makes it even less clear what happened.
Raise an exception (do not let the error pass silently).
This has the advantage of making it clear an error happened and what happened but may not always be the preferred behavior eg. if the rest of an algorithm is stopped due to an uncaught exception.
You could either
2.5) You could make a flag if the exception should pass silently or not (which should be the default? hard to say)
To 2):
Python support raising exceptions from a given context like so:
which will read as:
or (what you more likely want) to extend the existing exception like so:
which will read as:
For a longer discussion about the topic and also Python 2 conform solutions see: https://stackoverflow.com/questions/9157210/how-do-i-raise-the-same-exception-with-a-custom-message-in-python
The text was updated successfully, but these errors were encountered: