**[Reproduction of the error here](https://bitbucket.org/szabkel/emptyfileonexceptionrepro/).** *Please remove the comments before the exception throwing to see the problem. Path is: `http://localhost:8080/api/download`*

**Original Question:**
I am allowing users to download reports using JasperReports in an Angular7 App, but **the problem is only connected to Spring Boot**. The report generation works, but I can't get the file download to behave as I expected.

Currently:
The download link is used with an `href`, link with `target="_blank"`. The user clicks on it and the browser opens a new tab (in the background) and pops-up the `File Save As` window. If everything is okay, the file is saved without a problem. However if there is an exception during the PDF generation somewhere, the browser still pops-up the `File Save As` window and allows the user to save the file, it will complete, but the file will be `0 bytes`.

Should be: **When there is an exception, the browser should open a new tab with an error message of some sort, but If If there were no errors, it should display the File Save As window.**

Code:

```
@GetMapping("/salary-report/{id}")
public void generateSalaryReport(@PathVariable("id") long salaryReportId, HttpServletResponse response) throws IOException, JRException, SQLException {
    JasperPrint jasperPrint;
    var salaryReport = salaryReportRepositoryEx.findById(salaryReportId).orElseThrow(ResourceNotFoundException::new);

    try (OutputStream out = response.getOutputStream()) {
        HashMap<String, Object> parameters = new HashMap<>();

        parameters.put("ReportId", salaryReport.getId());

        // Set meta data
        response.setContentType("application/x-download");
        response.setHeader(
            "Content-Disposition",
            String.format("attachment; filename=\"%s%s-report%s-%s-%s.pdf\"",
                .... parameters
            )
        );

        // Set report
        jasperPrint = salaryReportJasperReport.render(parameters); // exception usually here
        JasperExportManager.exportReportToPdfStream(jasperPrint, out);
    } catch (Exception e) {
        // I tried changing the content type on Exception, but the same
        response.setContentType("text/plain");
        response.setHeader("Content-Disposition", null);
        throw e;
    }
}

```

HTML Code with the link (Angular7):

```
<td>
    <a [href]="serverApiUrl+'/jasper/salary-report/'+salaryReport.id"
       target="_blank"
    >
        PDF Download
    </a>
</td>

```

**Edit:** If I just manually navigate to a full download URL, same thing happens.

**Edit2:** Tried it in postman too. Using an invalid report id returns the expected 404 Json (`ResourceNotFoundException`), but moving forward with the code always returns 200 OK (even when I manually set the HTTP Code to 500 in the catch block) and the body is empty.

**Edit3:**
I tried using an exception handler:

```
@ResponseStatus(code = HttpStatus.INTERNAL_SERVER_ERROR)
public class JasperReportGenerationFailedException extends Exception {
    public JasperReportGenerationFailedException() {
        super();
    }

    public JasperReportGenerationFailedException(String message) {
        super(message);
    }

    public JasperReportGenerationFailedException(String message, Throwable cause) {
        super(message, cause);
    }

    public JasperReportGenerationFailedException(Throwable cause) {
        super(cause);
    }

    protected JasperReportGenerationFailedException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
        super(message, cause, enableSuppression, writableStackTrace);
    }
}

 @ExceptionHandler(JasperReportGenerationFailedException.class )
    public ResponseEntity<String> handleJasperException(JasperReportGenerationFailedException ex) {
        log.error("Salary Report generation failed.", ex);
        return new ResponseEntity<>(ex.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR);
    }

@GetMapping("/salary-report/{id}")
public void generateSalaryReport(@PathVariable("id") long salaryReportId, HttpServletResponse response) throws JasperReportGenerationFailedException {
    JasperPrint jasperPrint;
    var salaryReport = salaryReportRepositoryEx.findById(salaryReportId).orElseThrow(ResourceNotFoundException::new);

    try (OutputStream out = response.getOutputStream()) {
        HashMap<String, Object> parameters = new HashMap<>();

        parameters.put("ReportId", salaryReport.getId());

        // Set meta data
        response.setContentType("application/x-download");
        response.setHeader(
            "Content-Disposition",
            ...
            )
        );

        if (1 == 1/1) { // for testing, i always throw
            throw new Exception("Test");
        }
        // Set report
        jasperPrint = salaryReportJasperReport.render(parameters);
        JasperExportManager.exportReportToPdfStream(jasperPrint, out);
    } catch (Exception e) {
        throw new JasperReportGenerationFailedException(e);
    }
}

```