2
0
mirror of https://github.com/inventree/InvenTree.git synced 2025-04-28 19:46:46 +00:00

Handle errors when printing reports (#5360) (#5361)

- Re-throw as a ValidationError
- Results in a 400 error, not a 500

(cherry picked from commit 5f3d3b28b367e4ead79aeafc34c8c8da4d7564cf)

Co-authored-by: Oliver <oliver.henry.walters@gmail.com>
This commit is contained in:
github-actions[bot] 2023-07-28 14:23:43 +10:00 committed by GitHub
parent afa7ed873f
commit 946fe2df29
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -18,6 +18,7 @@ import InvenTree.helpers
import order.models import order.models
import part.models import part.models
from InvenTree.api import MetadataView from InvenTree.api import MetadataView
from InvenTree.exceptions import log_error
from InvenTree.filters import InvenTreeSearchFilter from InvenTree.filters import InvenTreeSearchFilter
from InvenTree.mixins import ListAPI, RetrieveAPI, RetrieveUpdateDestroyAPI from InvenTree.mixins import ListAPI, RetrieveAPI, RetrieveUpdateDestroyAPI
from stock.models import StockItem, StockItemAttachment from stock.models import StockItem, StockItemAttachment
@ -181,78 +182,90 @@ class ReportPrintMixin:
# Start with a default report name # Start with a default report name
report_name = "report.pdf" report_name = "report.pdf"
# Merge one or more PDF files into a single download try:
for item in items_to_print: # Merge one or more PDF files into a single download
report = self.get_object() for item in items_to_print:
report.object_to_print = item report = self.get_object()
report.object_to_print = item
report_name = report.generate_filename(request) report_name = report.generate_filename(request)
output = report.render(request) output = report.render(request)
# Run report callback for each generated report # Run report callback for each generated report
self.report_callback(item, output, request) self.report_callback(item, output, request)
try: try:
if debug_mode: if debug_mode:
outputs.append(report.render_as_string(request)) outputs.append(report.render_as_string(request))
else: else:
outputs.append(output) outputs.append(output)
except TemplateDoesNotExist as e: except TemplateDoesNotExist as e:
template = str(e) template = str(e)
if not template: if not template:
template = report.template template = report.template
return Response( return Response(
{ {
'error': _(f"Template file '{template}' is missing or does not exist"), 'error': _(f"Template file '{template}' is missing or does not exist"),
}, },
status=400, status=400,
)
if not report_name.endswith('.pdf'):
report_name += '.pdf'
if debug_mode:
"""Contatenate all rendered templates into a single HTML string, and return the string as a HTML response."""
html = "\n".join(outputs)
return HttpResponse(html)
else:
"""Concatenate all rendered pages into a single PDF object, and return the resulting document!"""
pages = []
try:
for output in outputs:
doc = output.get_document()
for page in doc.pages:
pages.append(page)
pdf = outputs[0].get_document().copy(pages).write_pdf()
except TemplateDoesNotExist as e:
template = str(e)
if not template:
template = report.template
return Response(
{
'error': _(f"Template file '{template}' is missing or does not exist"),
},
status=400,
)
inline = common.models.InvenTreeUserSetting.get_setting('REPORT_INLINE', user=request.user, cache=False)
return InvenTree.helpers.DownloadFile(
pdf,
report_name,
content_type='application/pdf',
inline=inline,
) )
if not report_name.endswith('.pdf'): except Exception as exc:
report_name += '.pdf' # Log the exception to the database
log_error(request.path)
if debug_mode: # Re-throw the exception to the client as a DRF exception
"""Contatenate all rendered templates into a single HTML string, and return the string as a HTML response.""" raise ValidationError({
'error': 'Report printing failed',
html = "\n".join(outputs) 'detail': str(exc),
'path': request.path,
return HttpResponse(html) })
else:
"""Concatenate all rendered pages into a single PDF object, and return the resulting document!"""
pages = []
try:
for output in outputs:
doc = output.get_document()
for page in doc.pages:
pages.append(page)
pdf = outputs[0].get_document().copy(pages).write_pdf()
except TemplateDoesNotExist as e:
template = str(e)
if not template:
template = report.template
return Response(
{
'error': _(f"Template file '{template}' is missing or does not exist"),
},
status=400,
)
inline = common.models.InvenTreeUserSetting.get_setting('REPORT_INLINE', user=request.user, cache=False)
return InvenTree.helpers.DownloadFile(
pdf,
report_name,
content_type='application/pdf',
inline=inline,
)
def get(self, request, *args, **kwargs): def get(self, request, *args, **kwargs):
"""Default implementation of GET for a print endpoint. """Default implementation of GET for a print endpoint.