How can I handle errors when streaming a file using CORS and jQuery AJAX in JavaScript?

I need some help using a Blob in JavaScript.

Basically, I stream a file to save it on my computer from my server using CORS. However, how do I handle an error? I am having trouble with that.

Server 1

jQuery.ajax({
    xhr: () => {
        // the 'XHR' function creates a new 'XMLHttpRequest' object and
        // sets up an event listener to track the progress of the request
        let xhr = new window.XMLHttpRequest();
        xhr.addEventListener("progress", evt => {
            // handle progress events to track the amount of data loaded
            if (evt.lengthComputable) {
                let percentComplete = evt.loaded / evt.total;
                // TODO send the results to an animated progress bar on the page
            }
        }, false);

        // this internal approach allows us to customize the XHR object and its behavior before making the request.
        // in this case, an event listener for progress tracking is added to the XHR object before returning it.
        // By returning the XHR object, we effectively override the default XHR object that jQuery would use, thus
        // providing us with more control and customization options for the AJAX request
        return xhr;
    },
    type: "GET", // the request type
    url: link, // the URL to send the request to
    processData: false, // the data should not be processed
    contentType: false, // the data should not be converted to a query string
    cache: false, // disable caching
    timeout: 180000, // set the timeout for the request to 180 seconds (3 minutes)
    xhrFields: {
        responseType: 'blob' // force the response type to be a Blob object
    },
    /**
     * callback function to handle the 'successful' response
     * @data is the response data from the server
     * @status is the return code
     * @jqXHR is a parameter of the success callback function
     * it represents the jQuery XHR(XMLHttpRequest) object that encapsulates the HTTP response received from the server.
     * the 'jqXHR' object provides various properties and methods to access and manipulate the response data.
     * in the code, it is used to retrieve the value of the 'Content-Disposition' header from the response
     */
    success: (data, status, jqXHR) => {
        // we expect the data to be a 'blob' so we'll try to handle it
        let disposition = jqXHR.getResponseHeader('Content-Disposition');
        let filename = ''; // the filename to download (will be replaced by the headers and refined by regex)

        // debugging
        console.log(disposition);

        // if we have a valid response header and it was flagged that we have an attachment
        if (disposition && disposition.indexOf('attachment') !== -1) {
            // then extract the filename from the 'Content-Disposition' header
            let filenameRegex = /filename[^;=n]*=((['"]).*?2|[^;n]*)/;
            let matches = filenameRegex.exec(disposition);

            // replace any quotes in the filename and update the filename variable
            if (matches != null && matches[1]) filename = matches[1].replace(/['"]/g, '');

            // call the 'saveAs' function with the retrieved data and filename
            // this will actually produce the file as a downloaded file in the web browser
            saveAs(data, filename);
        } else {
            // handle the scenario where the response is not an attachment
            errorCallback(jqXHR, 'error', 'Invalid Response Header');
        }
    },

    /**
     * handles an 'error' based response
     * @jqXHR represents the jQuery XHR (XMLHttpRequest) object that encapsulates the HTTP response received from the server.
     * @textStatus represents the status of the error ('timeout', 'error', or 'abort')
     * @errorThrown represents the error thrown, if any
     */
    error: function(jqXHR, textStatus, errorThrown) {
        //errorCallback(jqXHR, textStatus, errorThrown);
        let errorMessage = jqXHR.getResponseHeader('X-Powered-By');
        console.log(errorMessage);
    }
});

/** 
 * create a new 'Blob' object from the data array with a specified MIME type
 * @data is the response data from the server
 * @filename is the name of the file we wish to save as
 */
function saveAs(data, filename) {
    let rawdata = new Blob([data], {
        type: "application/octet-stream"
    });

    // Internet Explorer and Chrome browsers?
    if (window.navigator.msSaveOrOpenBlob) {
        window.navigator.msSaveBlob(rawdata, filename); // use the built-in function to save the file
    } else {
        // all other browsers?
        let menulink = window.document.createElement("a"); // create an 'a' element
        menulink.href = window.URL.createObjectURL(rawdata); // set the URL to the Blob via 'rawdata'
        menulink.download = filename; // set the download name
        document.body.appendChild(menulink); // create a child object on the page
        menulink.click(); // simulate a click event
        document.body.removeChild(menulink); // remove the child object on the page
    }
}

Server 2

header('Access-Control-Allow-Origin: *');
header('X-Error-Message: Second Server Test'); // Set the custom header with the error message
http_response_code(500);
die();

I tried setting a custom header in order to convey a message across (since I cannot use JSON as the object is forced to be a Blob) but that didn’t work. The header is being set, but I cannot read the header. I just get null at the moment in the console log when console.log(errorMessage) is called.