Why is every 400+ status code triggering onerror?

    function postDto(dto) {
        const xhr = new XMLHttpRequest();
        xhr.open("POST", api_url + "/scores/json");
        xhr.setRequestHeader("Content-Type", "application/json");
        xhr.onreadystatechange = () => {
            if (xhr.readyState === XMLHttpRequest.DONE) {
                if (xhr.status === 200)
                    postresponse = "Commit successful! View score " + "<a href='" + app_url + "/score/" + scoreName + "'>here</a>";
                else
                    postresponse = "Error: " + xhr.status + " - " + xhr.statusText;
            }
        };
        xhr.onerror = () => postresponse = "An error occurred.";
        xhr.send(JSON.stringify(dto));
    }

I needed to make some HTTP requests in this code. I’m writing a plugin for Musescore 4 in QML.
Problem is, any 400+ status code falls on xhr.onerror. Any clue on how to do this right?

Obs.: I had to resort to using XMLHttpRequests because it’s the only HTTP library I know that QML works with. CORS is already configured, by the way.