1
0
mirror of https://github.com/netbox-community/netbox.git synced 2024-05-10 07:54:54 +00:00

Closes #11152: Add support to abort custom script gracefully (#11621)

Signed-off-by: Maximilian Wilhelm <max@sdn.clinic>
This commit is contained in:
Maximilian Wilhelm
2023-02-02 21:22:55 +01:00
committed by GitHub
parent 95b2acb603
commit 699edd049c
3 changed files with 29 additions and 1 deletions

View File

@ -142,6 +142,19 @@ obj.full_clean()
obj.save() obj.save()
``` ```
## Error handling
Sometimes things go wrong and a script will run into an `Exception`. If that happens and an uncaught exception is raised by the custom script, the execution is aborted and a full stack trace is reported.
Although this is helpful for debugging, in some situations it might be required to cleanly abort the execution of a custom script (e.g. because of invalid input data) and thereby make sure no changes are performed on the database. In this case the script can throw an `AbortScript` exception, which will prevent the stack trace from being reported, but still terminating the script's execution and reporting a given error message.
```python
from utilities.exceptions import AbortScript
if some_error:
raise AbortScript("Some meaningful error message")
```
## Variable Reference ## Variable Reference
### Default Options ### Default Options

View File

@ -21,7 +21,7 @@ from extras.models import JobResult
from extras.signals import clear_webhooks from extras.signals import clear_webhooks
from ipam.formfields import IPAddressFormField, IPNetworkFormField from ipam.formfields import IPAddressFormField, IPNetworkFormField
from ipam.validators import MaxPrefixLengthValidator, MinPrefixLengthValidator, prefix_validator from ipam.validators import MaxPrefixLengthValidator, MinPrefixLengthValidator, prefix_validator
from utilities.exceptions import AbortTransaction from utilities.exceptions import AbortScript, AbortTransaction
from utilities.forms import add_blank_choice, DynamicModelChoiceField, DynamicModelMultipleChoiceField from utilities.forms import add_blank_choice, DynamicModelChoiceField, DynamicModelMultipleChoiceField
from .context_managers import change_logging from .context_managers import change_logging
from .forms import ScriptForm from .forms import ScriptForm
@ -470,6 +470,14 @@ def run_script(data, request, commit=True, *args, **kwargs):
except AbortTransaction: except AbortTransaction:
script.log_info("Database changes have been reverted automatically.") script.log_info("Database changes have been reverted automatically.")
clear_webhooks.send(request) clear_webhooks.send(request)
except AbortScript as e:
script.log_failure(
f"Script aborted with error: {e}"
)
script.log_info("Database changes have been reverted due to error.")
logger.error(f"Script aborted with error: {e}")
job_result.set_status(JobResultStatusChoices.STATUS_ERRORED)
clear_webhooks.send(request)
except Exception as e: except Exception as e:
stacktrace = traceback.format_exc() stacktrace = traceback.format_exc()
script.log_failure( script.log_failure(

View File

@ -24,6 +24,13 @@ class AbortRequest(Exception):
self.message = message self.message = message
class AbortScript(Exception):
"""
Raised to cleanly abort a script.
"""
pass
class PermissionsViolation(Exception): class PermissionsViolation(Exception):
""" """
Raised when an operation was prevented because it would violate the Raised when an operation was prevented because it would violate the