Selaa lähdekoodia

Closes #13334: Record error message on failed jobs (#14106)

Jeremy Stretch 2 vuotta sitten
vanhempi
commit
7323668dd0

+ 1 - 1
netbox/core/api/serializers.py

@@ -69,5 +69,5 @@ class JobSerializer(BaseModelSerializer):
         model = Job
         fields = [
             'id', 'url', 'display', 'object_type', 'object_id', 'name', 'status', 'created', 'scheduled', 'interval',
-            'started', 'completed', 'user', 'data', 'job_id',
+            'started', 'completed', 'user', 'data', 'error', 'job_id',
         ]

+ 1 - 1
netbox/core/jobs.py

@@ -25,7 +25,7 @@ def sync_datasource(job, *args, **kwargs):
         job.terminate()
 
     except Exception as e:
-        job.terminate(status=JobStatusChoices.STATUS_ERRORED)
+        job.terminate(status=JobStatusChoices.STATUS_ERRORED, error=str(e))
         DataSource.objects.filter(pk=datasource.pk).update(status=DataSourceStatusChoices.FAILED)
         if type(e) in (SyncError, JobTimeoutException):
             logging.error(e)

+ 18 - 0
netbox/core/migrations/0006_job_add_error_field.py

@@ -0,0 +1,18 @@
+# Generated by Django 4.2.6 on 2023-10-23 20:28
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('core', '0005_job_created_auto_now'),
+    ]
+
+    operations = [
+        migrations.AddField(
+            model_name='job',
+            name='error',
+            field=models.TextField(blank=True, editable=False),
+        ),
+    ]

+ 8 - 1
netbox/core/models/jobs.py

@@ -92,6 +92,11 @@ class Job(models.Model):
         null=True,
         blank=True
     )
+    error = models.TextField(
+        verbose_name=_('error'),
+        editable=False,
+        blank=True
+    )
     job_id = models.UUIDField(
         verbose_name=_('job ID'),
         unique=True
@@ -158,7 +163,7 @@ class Job(models.Model):
         # Handle webhooks
         self.trigger_webhooks(event=EVENT_JOB_START)
 
-    def terminate(self, status=JobStatusChoices.STATUS_COMPLETED):
+    def terminate(self, status=JobStatusChoices.STATUS_COMPLETED, error=None):
         """
         Mark the job as completed, optionally specifying a particular termination status.
         """
@@ -168,6 +173,8 @@ class Job(models.Model):
 
         # Mark the job as completed
         self.status = status
+        if error:
+            self.error = error
         self.completed = timezone.now()
         self.save()
 

+ 1 - 1
netbox/core/tables/jobs.py

@@ -47,7 +47,7 @@ class JobTable(NetBoxTable):
         model = Job
         fields = (
             'pk', 'id', 'object_type', 'object', 'name', 'status', 'created', 'scheduled', 'interval', 'started',
-            'completed', 'user', 'job_id',
+            'completed', 'user', 'error', 'job_id',
         )
         default_columns = (
             'pk', 'id', 'object_type', 'object', 'name', 'status', 'created', 'started', 'completed', 'user',

+ 1 - 1
netbox/extras/management/commands/runscript.py

@@ -59,7 +59,7 @@ class Command(BaseCommand):
                 logger.error(f"Exception raised during script execution: {e}")
                 clear_webhooks.send(request)
                 job.data = ScriptOutputSerializer(script).data
-                job.terminate(status=JobStatusChoices.STATUS_ERRORED)
+                job.terminate(status=JobStatusChoices.STATUS_ERRORED, error=str(e))
 
             logger.info(f"Script completed in {job.duration}")
 

+ 3 - 3
netbox/extras/reports.py

@@ -40,8 +40,8 @@ def run_report(job, *args, **kwargs):
 
     try:
         report.run(job)
-    except Exception:
-        job.terminate(status=JobStatusChoices.STATUS_ERRORED)
+    except Exception as e:
+        job.terminate(status=JobStatusChoices.STATUS_ERRORED, error=str(e))
         logging.error(f"Error during execution of report {job.name}")
     finally:
         # Schedule the next job if an interval has been set
@@ -230,7 +230,7 @@ class Report(object):
             stacktrace = traceback.format_exc()
             self.log_failure(None, f"An exception occurred: {type(e).__name__}: {e} <pre>{stacktrace}</pre>")
             logger.error(f"Exception raised during report execution: {e}")
-            job.terminate(status=JobStatusChoices.STATUS_ERRORED)
+            job.terminate(status=JobStatusChoices.STATUS_ERRORED, error=str(e))
 
         # Perform any post-run tasks
         self.post_run()

+ 1 - 1
netbox/extras/scripts.py

@@ -519,7 +519,7 @@ def run_script(data, request, job, commit=True, **kwargs):
                 logger.error(f"Exception raised during script execution: {e}")
             script.log_info("Database changes have been reverted due to error.")
             job.data = ScriptOutputSerializer(script).data
-            job.terminate(status=JobStatusChoices.STATUS_ERRORED)
+            job.terminate(status=JobStatusChoices.STATUS_ERRORED, error=str(e))
             clear_webhooks.send(request)
 
         logger.info(f"Script completed in {job.duration}")

+ 6 - 0
netbox/templates/core/job.html

@@ -35,6 +35,12 @@
               <th scope="row">{% trans "Status" %}</th>
               <td>{% badge object.get_status_display object.get_status_color %}</td>
             </tr>
+            {% if object.error %}
+              <tr>
+                <th scope="row">{% trans "Error" %}</th>
+                <td>{{ object.error }}</td>
+              </tr>
+            {% endif %}
             <tr>
               <th scope="row">{% trans "Created By" %}</th>
               <td>{{ object.user|placeholder }}</td>