elninotech / uppload

📁 JavaScript image uploader and editor, no backend required
https://uppload.js.org
MIT License
1.85k stars 128 forks source link

Upload error handling #611

Open jean-gui opened 3 years ago

jean-gui commented 3 years ago

Describe the bug Using Uppload 3.2.1 with the default XHR uploader I don't understand how to handle errors. What should the endpoint return so that Uppload understands something went wrong? I've tried returning different HTTP codes (400, 406, 500), but Uppload doesn't display any message and even worse, tries to replace the image defined in the bind property with a dummy URL ending with /undefined, unless the response payload contains {'url': 'foo'} in which case it will replace the bound image with 'foo' (even if the POST did not result in a 200 OK).

I have also tried listening to the "error" and "upload" events, but "error" only seems to be fired if the server is not responding at all, in which case the error message is undefined. On the contrary, the "upload" one is fired even when the response contains an HTTP error code.

To Reproduce I use the following code:

const uploader = new Uppload({
    lang: en,
    bind: document.querySelector("#image-wrapper img.uploadable-image"),
    call: editPic,
    uploader: xhrUploader({
        endpoint: endpoint,
        fileKeyName: 'form[file]'
    }),
    maxWidth: 400,
    compressionToMime: "image/jpeg"
});
uploader.use([
    new Local(),
    new Camera(),
    new URL(),
    new Crop({aspectRatio: ratio})
]);

const errorLogger = (error) => {
    console.log("The error message is", error);
};
uploader.on("error", errorLogger);
const okLogger = (ok) => {
    console.log("The ok message is", ok);
};
uploader.on("upload", okLogger);

Expected behavior If the XHR endpoint returns an HTTP error code, the bound image should not be updated, an error message should be displayed (ideally coming from the response to the POST) and an error event should probably be fired.

Do I need to write my own uploader? It feels like the provided uploaders should handle such errors properly, not being able to send feedback to the user kinda makes them pretty unusable in practice.

Desktop (please complete the following information):

Thanks.

JhonGdl commented 2 years ago

I am trying to handle loading errors as well. @jean-gui You've made it?

jean-gui commented 2 years ago

I don't really remember since that was quite some time ago, but I don't think so. I'm forcing the page to reload after an upload attempt instead, so that I can display errors computed on the endpoint:

const uploader = new Uppload({
    lang: en,
    call: editPic,
    uploader: xhrUploader({
        endpoint: endpoint,
        fileKeyName: 'form[file]',
        responseFunction: () => {
            // Always reload the page regardless of whether the upload succeeded or not
            document.location.reload();
        }
    }),
    ...
});

Hope that helps.

alicezuberg930 commented 2 weeks ago

Um I think there is a file in the src/uploaders folder name xhr.ts that create a request to the backend endpoint that you can alter to return an error from the backend. in the xhrUploader function alter the "load" eventlistener like this.

xmlHttp.addEventListener("load", () => {
    const responseText = xmlHttp.responseText;
    if (typeof responseFunction === "function")
        return resolve(responseFunction(responseText));
    const json = JSON.parse(responseText);
    if(xmlHttp.status == 400) {
        return reject(json["error"])
    }
    return resolve(json[responseKey]);
});

The 400 is the status and the "error" key is what I specified and returned from backend. you can change the key and the status code to anything you want though