-
Notifications
You must be signed in to change notification settings - Fork 2.6k
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
Fixes: #15016 - Catch AssertionError from cable trace and throw ValidationError #16384
base: develop
Are you sure you want to change the base?
Conversation
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.
The use of assert
statements in this logic was primarily for sanity-checking during initial development; they shouldn't be relied upon as true validation checks. (They aren't even run when __debug__
is False.)
If the use case in #15016 is not supported, we need to add specific validation logic to check for and report on it.
This PR has been automatically marked as stale because it has not had recent activity. It will be closed automatically if no further action is taken. |
…of a validation error.
This PR has been automatically marked as stale because it has not had recent activity. It will be closed automatically if no further action is taken. |
This PR has been automatically marked as stale because it has not had recent activity. It will be closed automatically if no further action is taken. |
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'm afraid this still doesn't address my primary concern: Validation of cable state needs to be performed prior to the point where we're generating cable paths. (Again, the original assertions were just sanity checks.) This should ideally be performed on each model under clean()
.
Additionally, as a rule generic views should not check for and handle any model-specific exceptions.
The issue is there isn't really a way to validate the cable state prior to the cable being saved, without effectively duplicating all the work done in the cable path generation. The main reason for this is because a lot of these assertion checks are dependant on sibling cable state further down the path, not just part of the existing cable save, which isn't known until you generate the full path. We would effectively be running the from_origin twice in this instance, once to validate the cable state and once to save it. Take for example this path, where Switch 1, interface1 is what you are connecting (the rest is fully formed):
You can validate FP1-1 and FP1-2 because they are connected. But you can't run any of the peer validations on FP2-1 and FP2-2 because FP2-1 doesn't know that FP2-2 will be part of that same path until Interface1 is connect and that path is fully formed. I can take another pass at it, and see if I can have it run this in clean() first, but most of the parts of this rely on objects existing in the database already as well, so this would likely need a complete re-write, which I was trying to avoid doing. |
This PR has been automatically marked as stale because it has not had recent activity. It will be closed automatically if no further action is taken. |
This PR has been automatically marked as stale because it has not had recent activity. It will be closed automatically if no further action is taken. |
@@ -319,6 +320,12 @@ def post(self, request, *args, **kwargs): | |||
form.add_error(None, e.message) | |||
clear_events.send(sender=self) | |||
|
|||
# Catch any validation errors thrown in the model.save() or form.save() methods | |||
except UnsupportedCablePath as e: |
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 don't think this is the right place to handle the exception, for two reasons. First, we want to avoid introducing any model-specific logic within a generic view. Second, this addresses only the UI workflow; it doesn't account for an API-driven change.
A cleaner approach might be to catch UnsupportedCablePath
raised by trace_paths.send()
under Cable.save()
and raise an AbortRequest
exception in turn. We should be able to preserve the error message text in doing so.
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.
Should be ready for your review again, I think this is how you envisioned it.
…into 15016-fix-assertionerror-when-saving-cable
…ving-cable' into 15016-fix-assertionerror-when-saving-cable # Conflicts: # netbox/netbox/views/generic/object_views.py
Fixes: #15016 - Catch AssertionError from cable trace and throw ValidationError