Handle editors upload field exceptions

Handle editors upload field exceptions

theAnimalixtheAnimalix Posts: 35Questions: 12Answers: 2

Hey,

I'm using ajax object configuration for upload type of input. Everything works great, I just have an issue where if validation of uploaded image is rejected, server returns status code 422, so datatables displays "A server error occurred while uploading the file".

For other ajax requests I was able to handle this inside "error" function, but in this case it doesn't seem to be fired. Bellow is my code:

{
    label: 'Image:',
    name: IMAGE_NAME,
    ajax: {
        url: route('dt.post'),
        type: 'POST',
        data: (data) => {
            data._token = window.Laravel.csrfToken;
        },
        dataFilter: function (response) {
            const json = JSON.parse(response);
            $.each(json.files, function ( table, files ) {
                $.fn.dataTable.Editor.files[table] = files;
            });
            return response;
        },
        error: function (xhr, e/*, thrown*/) {
            let data = xhr.responseJSON;
            if (data && data.hasOwnProperty('fieldErrors')){
//                success(data);
            } else {
//                error(xhr, e, thrown);
            }
        }
    },
    type: 'upload',
    display: function ( file_id ) {
        ...
    },
    clearText: "Clear",
    noImageText: '-'
}

Any idea why error function is not fired when server code != 200?

Beside this approach I also tried to use ajax function instead of object function(method, url, data, success, error) (I use this as default method all over the project) so that I was able to call success or error callback, depending on what happened. If I add this to my upload field, upload field will completely ignore function and just make a POST request to the same page user is currently on. This works for DataTables data calls though, so not sure why it doesn't here...

Is there a way to handle validation errors and prevent "A server error occurred while uploading the file" getting displayed for upload field?

P.S.: After using DataTables for 5+ years I think, I think I could easily say it's one of the most advanced and flexible packages I ever used. GJ Allan and team :)

Answers

  • allanallan Posts: 61,635Questions: 1Answers: 10,092 Site admin

    Thank you for your kind words :).

    Your error callback isn't being called because Editor's own error handler is overwriting it I'm afraid. This is what Editor uses:

                error: function ( xhr ) {
                    editor._event( 'uploadXhrError', [ conf.name, xhr ] );
                    editor.error( conf.name, generalError );
    
                    progressCallback( conf );
                }
    

    uploadXhrError is the error that is triggered and that can be used to control the errors to some extent, but that second line in the function means that the field error will always be shown regardless of what the error event handler does.

    In retrospect, based on your use case, that is back to front. I'll swap the order of those two for the next release. You might want to do that in your local copy if you want full control of the error messages until then.

    Regards,
    Allan

  • theAnimalixtheAnimalix Posts: 35Questions: 12Answers: 2

    Hey Alan,

    Thank you very much for your reply. ...just giving credits where they belong. :) Btw, is Alan = Team (I think I only see you replying here)? :)

    Sorry, I realized that uploadXhrError is actually in documentation, so should check better next time.

    But right, that 2nd line in source code is a bit problematic since it always shows form error, but instead I would need to show upload field error (411 error is returned if image validation fails...png,size,dimensions,...).

    However, I don't see how switching the order of those 2 lines would solve this...since editor.error() would still get called and form error rendered (I tested it here). I guess the only workaround would be to manually hide displayed form error and manually display field error?

    I feel the best solution to this problem (if it's possible) would be to allow us to use the same callbacks that editor uses for ajax requests:

    $.fn.dataTable.Editor({
       //....
       ajax: dtEditorAjaxCall,
       //...
    }
    
    function dtEditorAjaxCall(method, url, data, success, error) {
        $.ajax({
            //... general ajax stuff
            success: function (response) {
                success(response);
            },
            error: function (xhr, e, thrown) {
                let data = xhr.responseJSON;
                if (data && data.hasOwnProperty('fieldErrors'))
                    success(data);
                else
                    error(xhr, e, thrown);
            }
        });
    }
    

    This way in my code I can call success(data) if there was a validation error...which will then display field errors correctly (without form error). In other/unhandled cases I just call error(xhr, e, thrown) callback to show the form error.

  • allanallan Posts: 61,635Questions: 1Answers: 10,092 Site admin

    Btw, is Alan = Team (I think I only see you replying here)?

    Nope. Thankfully(!) Colin is on the case here in the forum for the majority of support threads. And Sandy is getting more involved (we are a team of three now - although yes, I'm the original developer - it means they have to call me "boss" ;-) ).

    I guess the only workaround would be to manually hide displayed form error and manually display field error?

    If you do editor.error(''); in the call back, it should result in nothing being shown to the end user since the browser will queue draw updates.

    If that doesn't work for you, I'll look at allowing a preventDefault type behaviour. I'd rather keep the error handler as is, otherwise you'll need to reimplement some of the internal upload logic Editor has in order to reset on error.

    Allan

  • theAnimalixtheAnimalix Posts: 35Questions: 12Answers: 2

    OK, Boss. :) Happy to hear that you have help and team is growing!

    Oh, you are right...I didn't think about calling error on editor directly....thanks for the hint! The error is actually a field error, so one also has to pass field name.

    I just implemented it for 1 upload field in form, and code looks like this:

    DT_EDITOR.on('uploadXhrError', function (e, fieldName, xhr) {
            let data = xhr.responseJSON;
            if (data && data.fieldErrors){
                //override default form field error with validation error message
                DT_EDITOR.error(fieldName, data.fieldErrors[0].status);
            }
        });
    

    Plus as you've suggested I switched the lines order in DT editor source code. It's seems like a good solution.

    I guess this should also work for multiple upload inputs on a single form (I only tested with 1).

    Thank you Allan again and good luck!

This discussion has been closed.