Skip to content

Commit d4272b9

Browse files
committed
Simplify returning errors using new ErrorResponse class
Signed-off-by: tdruez <[email protected]>
1 parent 1188059 commit d4272b9

File tree

1 file changed

+35
-46
lines changed

1 file changed

+35
-46
lines changed

scanpipe/api/views.py

Lines changed: 35 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,18 @@
6363
scanpipe_app = apps.get_app_config("scanpipe")
6464

6565

66+
class ErrorResponse(Response):
67+
def __init__(self, message, status_code=status.HTTP_400_BAD_REQUEST, **kwargs):
68+
# If message is already a dict, use it as-is
69+
if isinstance(message, dict):
70+
data = message
71+
else:
72+
# Otherwise, wrap string in {"status": message}
73+
data = {"status": message}
74+
75+
super().__init__(data=data, status=status_code, **kwargs)
76+
77+
6678
class ProjectFilterSet(django_filters.rest_framework.FilterSet):
6779
name = django_filters.CharFilter()
6880
name__contains = django_filters.CharFilter(
@@ -178,8 +190,7 @@ def results_download(self, request, *args, **kwargs):
178190
elif format == "all_outputs":
179191
output_file = output.to_all_outputs(project)
180192
else:
181-
message = {"status": f"Format {format} not supported."}
182-
return Response(message, status=status.HTTP_400_BAD_REQUEST)
193+
return ErrorResponse(f"Format {format} not supported.")
183194

184195
filename = output.safe_filename(f"scancodeio_{project.name}_{output_file.name}")
185196
return FileResponse(
@@ -198,8 +209,7 @@ def summary(self, request, *args, **kwargs):
198209
summary_file = project.get_latest_output(filename="summary")
199210

200211
if not summary_file:
201-
message = {"error": "Summary file not available"}
202-
return Response(message, status=status.HTTP_400_BAD_REQUEST)
212+
return ErrorResponse({"error": "Summary file not available"})
203213

204214
summary_json = json.loads(summary_file.read_text())
205215
return Response(summary_json)
@@ -226,14 +236,14 @@ def report(self, request, *args, **kwargs):
226236
),
227237
"choices": ", ".join(model_choices),
228238
}
229-
return Response(message, status=status.HTTP_400_BAD_REQUEST)
239+
return ErrorResponse(message)
230240

231241
if model not in model_choices:
232242
message = {
233243
"error": f"{model} is not on of the valid choices",
234244
"choices": ", ".join(model_choices),
235245
}
236-
return Response(message, status=status.HTTP_400_BAD_REQUEST)
246+
return ErrorResponse(message)
237247

238248
output_file = output.get_xlsx_report(
239249
project_qs=project_qs,
@@ -256,8 +266,7 @@ def get_filtered_response(
256266
"""
257267
filterset = filterset_class(data=request.GET, queryset=queryset)
258268
if not filterset.is_valid():
259-
message = {"errors": filterset.errors}
260-
return Response(message, status=status.HTTP_400_BAD_REQUEST)
269+
return ErrorResponse({"errors": filterset.errors})
261270

262271
queryset = filterset.qs
263272
paginated_qs = self.paginate_queryset(queryset)
@@ -315,14 +324,12 @@ def file_content(self, request, *args, **kwargs):
315324
try:
316325
codebase_resource = codebase_resources.get(path=path)
317326
except ObjectDoesNotExist:
318-
message = {"status": "Resource not found. Use ?path=<resource_path>"}
319-
return Response(message, status=status.HTTP_400_BAD_REQUEST)
327+
return ErrorResponse("Resource not found. Use ?path=<resource_path>")
320328

321329
try:
322330
file_content = codebase_resource.file_content
323331
except OSError:
324-
message = {"status": "File not available"}
325-
return Response(message, status=status.HTTP_400_BAD_REQUEST)
332+
return ErrorResponse("File not available")
326333

327334
return Response({"file_content": file_content})
328335

@@ -341,32 +348,29 @@ def add_pipeline(self, request, *args, **kwargs):
341348
{"status": "Pipeline added."}, status=status.HTTP_201_CREATED
342349
)
343350

344-
message = {"status": f"{pipeline} is not a valid pipeline."}
345-
return Response(message, status=status.HTTP_400_BAD_REQUEST)
351+
return ErrorResponse(f"{pipeline} is not a valid pipeline.")
346352

347353
message = {
348354
"status": "Pipeline required.",
349355
"pipelines": list(scanpipe_app.pipelines.keys()),
350356
}
351-
return Response(message, status=status.HTTP_400_BAD_REQUEST)
357+
return ErrorResponse(message)
352358

353359
@action(detail=True, methods=["get", "post"])
354360
def add_input(self, request, *args, **kwargs):
355361
project = self.get_object()
356362

357363
if not project.can_change_inputs:
358-
message = {
359-
"status": "Cannot add inputs once a pipeline has started to execute."
360-
}
361-
return Response(message, status=status.HTTP_400_BAD_REQUEST)
364+
return ErrorResponse(
365+
"Cannot add inputs once a pipeline has started to execute."
366+
)
362367

363368
upload_file = request.data.get("upload_file")
364369
upload_file_tag = request.data.get("upload_file_tag", "")
365370
input_urls = request.data.get("input_urls", [])
366371

367372
if not (upload_file or input_urls):
368-
message = {"status": "upload_file or input_urls required."}
369-
return Response(message, status=status.HTTP_400_BAD_REQUEST)
373+
return ErrorResponse("upload_file or input_urls required.")
370374

371375
if upload_file:
372376
project.add_upload(upload_file, tag=upload_file_tag)
@@ -398,16 +402,13 @@ def add_webhook(self, request, *args, **kwargs):
398402
)
399403

400404
# Return validation errors
401-
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
405+
return ErrorResponse(serializer.errors)
402406

403407
def destroy(self, request, *args, **kwargs):
404408
try:
405409
return super().destroy(request, *args, **kwargs)
406410
except RunInProgressError:
407-
return Response(
408-
{"status": "Cannot delete project while a run is in progress."},
409-
status=status.HTTP_400_BAD_REQUEST,
410-
)
411+
return ErrorResponse("Cannot delete project while a run is in progress.")
411412

412413
@action(detail=True, methods=["get", "post"])
413414
def archive(self, request, *args, **kwargs):
@@ -429,10 +430,7 @@ def archive(self, request, *args, **kwargs):
429430
remove_output=request.data.get("remove_output"),
430431
)
431432
except RunInProgressError:
432-
return Response(
433-
{"status": "Cannot archive project while a run is in progress."},
434-
status=status.HTTP_400_BAD_REQUEST,
435-
)
433+
return ErrorResponse("Cannot archive project while a run is in progress.")
436434

437435
return Response({"status": f"The project {project} has been archived."})
438436

@@ -451,10 +449,7 @@ def reset(self, request, *args, **kwargs):
451449
execute_now=request.data.get("execute_now", False),
452450
)
453451
except RunInProgressError:
454-
return Response(
455-
{"status": "Cannot reset project while a run is in progress."},
456-
status=status.HTTP_400_BAD_REQUEST,
457-
)
452+
return ErrorResponse("Cannot reset project while a run is in progress.")
458453
else:
459454
message = f"The {project} project has been reset."
460455
return Response({"status": message})
@@ -468,8 +463,7 @@ def outputs(self, request, *args, **kwargs):
468463
if file_path.exists():
469464
return FileResponse(file_path.open("rb"))
470465

471-
message = {"status": f"Output file {filename} not found"}
472-
return Response(message, status=status.HTTP_400_BAD_REQUEST)
466+
return ErrorResponse(f"Output file {filename} not found")
473467

474468
action_url = self.reverse_action(self.outputs.url_name, args=[project.pk])
475469
output_data = [
@@ -544,14 +538,11 @@ class RunViewSet(mixins.RetrieveModelMixin, viewsets.GenericViewSet):
544538
def start_pipeline(self, request, *args, **kwargs):
545539
run = self.get_object()
546540
if run.task_end_date:
547-
message = {"status": "Pipeline already executed."}
548-
return Response(message, status=status.HTTP_400_BAD_REQUEST)
541+
return ErrorResponse("Pipeline already executed.")
549542
elif run.task_start_date:
550-
message = {"status": "Pipeline already started."}
551-
return Response(message, status=status.HTTP_400_BAD_REQUEST)
543+
return ErrorResponse("Pipeline already started.")
552544
elif run.task_id:
553-
message = {"status": "Pipeline already queued."}
554-
return Response(message, status=status.HTTP_400_BAD_REQUEST)
545+
return ErrorResponse("Pipeline already queued.")
555546

556547
transaction.on_commit(run.start)
557548

@@ -562,8 +553,7 @@ def stop_pipeline(self, request, *args, **kwargs):
562553
run = self.get_object()
563554

564555
if run.status != run.Status.RUNNING:
565-
message = {"status": "Pipeline is not running."}
566-
return Response(message, status=status.HTTP_400_BAD_REQUEST)
556+
return ErrorResponse("Pipeline is not running.")
567557

568558
run.stop_task()
569559
return Response({"status": f"Pipeline {run.pipeline_name} stopped."})
@@ -573,8 +563,7 @@ def delete_pipeline(self, request, *args, **kwargs):
573563
run = self.get_object()
574564

575565
if run.status not in [run.Status.NOT_STARTED, run.Status.QUEUED]:
576-
message = {"status": "Only non started or queued pipelines can be deleted."}
577-
return Response(message, status=status.HTTP_400_BAD_REQUEST)
566+
return ErrorResponse("Only non started or queued pipelines can be deleted.")
578567

579568
run.delete_task()
580569
return Response({"status": f"Pipeline {run.pipeline_name} deleted."})

0 commit comments

Comments
 (0)