-
Notifications
You must be signed in to change notification settings - Fork 278
Add new exceptions file for exceptions in the new code #1725
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
Add new exceptions file for exceptions in the new code #1725
Conversation
The only question that is left is do we think that |
Pull Request Test Coverage Report for Build 1693501800Warning: This coverage report may be inaccurate.This pull request's base commit is no longer the HEAD commit of its target branch. This means it includes changes from outside the original pull request, including, potentially, unrelated coverage changes.
Details
💛 - Coveralls |
eb5457d
to
ea6aaf6
Compare
I argument descriptions in the |
Let's not touch files that are part of the legacy code base. I think the location of exceptions.py WRT ngclient is not an issue: ngclient already "depends" on tuf.api so exceptions being there is not a problem. There is an issue though (and you may also be thinking about this one): there are exceptions that are clearly client specific (at least FetcherHTTPError) and having those defined in non-client module is not great... but it's also not the worst thing in the world. |
@@ -35,9 +35,9 @@ def fetch(self, url: str) -> Iterator[bytes]: | |||
url: A URL string that represents a file location. | |||
|
|||
Raises: | |||
tuf.exceptions.SlowRetrievalError: A timeout occurs while receiving |
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.
(this is more a generic comment)
I noticed that we refer to the full exception path; in other docstrings (including tuf/api/metadata), we use only the exception name. Not sure which should be the standard.
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.
My opinion is that we shouldn't use the full exception path as it can change (as it happened now).
I think is best if we use the module name as I did in the mentioned example exceptions.SlowRetrievalError
.
@jku 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.
I personally think including the "module path" at all is not very useful in docstrings: it just makes things harder to read. But if we do include them, then they should be complete
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 still want to have a quick look at all the errors (are they really something we want to keep) but I left some initial comments about removing a lot of the code
ea6aaf6
to
044296b
Compare
I addressed all comments by @jku and @kairoaraujo by:
|
Some thinking on the exceptions we have / should have :
|
6ab2bc3
to
921b99c
Compare
After a conversation with @jku I agreed on both three points mentioned here and a few additional others. |
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 believe these are good changes overall, however we should make sure we do all of the exceptions API changes at roughly same time so it's not a constant churn: I am far less interested in the location of the exceptions file than how the exceptions are used in metadata API and ngclient. The remaining specific issues I know of are
- sslib exceptions in metadata api (Metadata API: Avoid raising securesystemslib exceptions #1734)
- verifying use and documentation of the download exceptions in ngclient/fetcher
It looks like we can do those separately (but the focus on this PR should be to verify that any changes are in line with these near future plans).
fe789ac
to
a956684
Compare
In a conversation with @lukpueh he mentioned that the name |
Either one works for me: RepositoryError is not completely self explanatory but I don't see a specific problem with it: Updater uses the error to mean "this error happens because of metadata we got from repository: The issue cannot be resolved without new metadata from repository": the point is that this is not a client bug, it's a problem on the repository end. I'd personally avoid an API change just to change the name but I can live with change as well. The other suggestions are really long. |
a99b09d
to
a0171dc
Compare
I rebased on top of develop and added a0171dc. Those are the only real changes here. |
a0171dc
to
c6d30e6
Compare
c6d30e6
to
c0620c4
Compare
I added a couple of simplifications in my latest commits including making (De)Serialize errors a RepositoryErros. On the question of the current exceptions: RepositoryErrors They allow us to test for those specific use cases without checking the exception messages. UnsignedMetadataError is useful when we want to denote problems with the keys or signatures. It’s used on multiple occasions to communicate different signing problems to the users such as Also, I think exceptions related to signatures and keys are useful to have their own exception as they show problems that need a more specific solution - resign, replace a key, etc. Then we have the TrustedMetadataSet errors. We have three of them BadVersionNumberError, ExpiredMetadataError, and LengthOrHashMismatchError. They are useful in order to test specific repository errors at the same time the user can just catch BadVersionNumberError is needed to test when:
ExpiredMetadataError is thrown when any of the metadata files has expired LengthOrHashMismatchError is raised when:
LengthOrHashMismatchError is caught twice in the ngclient:
On the question do we need additional exceptions? Here are the possible new exceptions I see:
DownloadErrors DownloadLengthMismatchError it’s used as expected and I think it makes sense to keep it for tests. SlowRetrievalError: I don’t have a strong opinion on this one. On one hand, I see it serves the purpose to unify all timeout exceptions into one on another hand I am asking how does that help us? Do we want to do that? FetcherHTTPError: I see that FetcherHTTPError is used almost everywhere for a variety of reasons:
and others. Then, I see that DownloadError is not used anywhere. |
Thanks for the research and for sharing your detailed insights, @MVrachev! I mostly agree with you:
|
I agree with you.
Agree with you that the prefix
I think splitting them is better. Those are two different use cases and having two different errors probably could shorten our messages (it needs to be tried).
Agree.
As the cases I described are more about missing information inside a metadata file it sounds to me it will be more appropriate to use
Can you emphasize more on that?
so, I think it makes sense to rename it to
Good suggestion. All of the exceptions we are catching and rethrowing as |
Okay great, looks like we are pretty much on the same page. Let's have @jku, who's usually more cautious when it comes to renames, also weigh in. :)
Without looking at the client implementation, I'd say that |
|
Let's defer the decision and take one final look at the issue shortly before the release, when we have resolved everything else (also see #1745 (comment)) @MVrachev, can you ticketize?
Agreed.
Thanks for the insights. |
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 a pretty good first iteration of cleaning up the exception taxonomy and suggest we merge as is.
But I'd like to pick up the discussion from this PR once more before 1.0. In particular I'd like to review wether:
- generic errors (
RepositoryError
,DownloadError
) that we raise should be more specific, - specific errors (
BadVersionNumberError,
LengthOrHashMismatchError`, etc.) really need to be that specific - built-in exceptions are used in an idiomatic fashion
- exception names aren't misleading
- all of above is consistent, i.e. there is no mix of generic and specific or custom and built-in exceptions, where there shouldn't be
Root.type, | ||
new_root.signed.version, | ||
self.root.signed.version, | ||
raise exceptions.BadVersionNumberError( |
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.
General question for exceptions raised in methods in this module:
If none of them are documented in the Raises
section of the method docstrings (they only mention the broad RepositoryError
), do we expect anyone to handle them? If we do, we should probably document them. E.g. the BadVersionNumberError
here, etc.
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.
Point 2 of issue #1784 is about that.
Add tuf/api/exceptions.py for exceptions in the new code. I copied the exceptions from tuf/exceptions.py with a few important decisions: 1. I only added the exceptions that are used in the new code 2. I removed the general "Error" class as we can directly inherit Exceptions 3. I tried grouping the exceptions by relevance 4. I removed the second argument "UnsignedMetadataError" as it's only kept for backward compatibility and is not used 5. I tried following the new code style guidelines and linted the file with our linters. Signed-off-by: Martin Vrachev <[email protected]>
Stop linting tuf/exceptions.py with mypy as we are going to use tuf/api/exceptions.py for exceptions in the new code. Signed-off-by: Martin Vrachev <[email protected]>
Make FetcherHTTPError a DownloadError as the error itself denotes an error happening during the download process. Signed-off-by: Martin Vrachev <[email protected]>
URLParsingError is a specific download error and is not clear what benefit it provides. It's used only once in the new code and the message says everything you need to know about the exception. Signed-off-by: Martin Vrachev <[email protected]>
ReplayedMetadataError is a subset of BadVersionNumberError and in a discussion with Jussi we realized that ReplayedMetadataError can be replaced by BadVersionNumberError with a good message. Signed-off-by: Martin Vrachev <[email protected]>
UnsupportedAlgorithmError is a detailed securesystemslib exception and there is no need for TUF to redefine it. Moreover which hash "algorithms" are allowed is work for securesystemslib not for TUF. It's only used once inside "Targetfile.from_data()" and there it's used to denote that there is a problem with the given argument. That's why this error can be just replaced with "ValueError". Signed-off-by: Martin Vrachev <[email protected]>
LengthOrHashMismatchError is a thrown when there are problems with metadata verification or problems from the repository side when looking it from the user's perspective. Signed-off-by: Martin Vrachev <[email protected]>
Signed-off-by: Martin Vrachev <[email protected]>
Signed-off-by: Martin Vrachev <[email protected]>
SerializationError and DeserializationError are both errors coming from the repository side looking from the clients point of view. That's why it makes sense to make them repository errors. Signed-off-by: Martin Vrachev <[email protected]>
We should document that "DownloadError" is thrown inside RequestsFetcher.fetch(). Signed-off-by: Martin Vrachev <[email protected]>
c0620c4
to
7bb916f
Compare
Rebased on top of develop.
These two points can be discussed in #1784.
Created an issue about it: #1785.
Issue #1786 is about that. |
Addresses @jku comment here: #1721 (comment)
Description of the changes being introduced by the pull request:
Add tuf/api/exceptions.py for exceptions in the new code.
I copied the exceptions from tuf/exceptions.py with a few important
decisions:
Exceptions.
signable
inUnsignedMetadataError
as it was onlykept for backward compatibility and is not used. (See 929b4b2 where it was added in
tuf/exceptions.py
)with our linters.
FetcherHTTPError
aDownloadError
URLParsingError
and replaced it with aDownloadError
ReplayedMetadataError
and replaced it withBadVersionNumberError
Additionally, I stopped linting tuf/exceptions.py with
mypy
as we are going to usetuf/api/exceptions.py
for exceptions in the new code.Signed-off-by: Martin Vrachev [email protected]
Please verify and check that the pull request fulfills the following
requirements: