Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I get the error status codes from a Vuex response?

I am trying to handle errors in my Laravel/Vue application. As far as I can tell, I have everything in place as I am seeing what I expect. However, I am unable to get/return the status code if the response is anything other than 200.

console.log('status: ', response.status); // 200

If the response is 400 (or anything other than 200), I am unable to read it.

console.log('status: ', response.status); // undefined

Here is what I am creating for a response in my Controller:

Controller.php

...

if ($exception->getCode() === 400) {
    return response()->json(['errors' =>
        [
            'title' => 'Bad Request',
            'detail' => 'The username or password you have entered is invalid',
        ],
    ], $exception->getCode());
}

In the network tab, the response is coming back as 400, and the response object looks like this:

{"errors":{"title":"Bad Request","detail":"The username or password you have entered is invalid"}}

Awesome!

The request in my Vue component looks like this (click event handler):

...

try {
    await this.$store.dispatch("user/signInWithEmailAndPassword", this.form)
        .then(response => {
            console.log('status: ', response.status);

                switch (response.status) {
                    case 200:
                        console.log('good to go!');
                        break;
                    case 400:
                        console.log('400 error');  // not getting here
                        break;
                    case 401:
                        console.log('401 error');  // or here
                        break;
                    default:
                        console.log('some other error');  // end up here all the time
                        break;
                    }
        })
        .catch(error => {
            console.log('SignInForm.authenticate error: ', error);
        });
} catch (error) {
    console.log("SignInForm.handleSubmit catch error:", error);
}

In my Vuex store, I am just returning the response from my service to see what I'm getting:

Vuex Store.vue

return await UserService.signInWithEmailAndPassword(credentials)
        .then(response => {
            return response;

        ...

UserService.vue

...

return await client.post('/v1/login', credentials)
    .then(response => {
        return response;
    })
    .catch(function (error) {
        console.log('UserService.signInWithEmailAndPassword error: ', error); // getting here
        return error;
    });

So far, the only luck I'm having is seeing this in my console:

UserService.signInWithEmailAndPassword error: Error: Request failed with status code 400

How can I read the 400 error code to show the error I really want? It seems all the pieces are there. I'm not handling the error response correctly. Thank you for any suggestions!

EDIT

I have updated my code to reflect your suggestions, and I believe it stems from not returning my UserService call correctly. Here's what I'm doing now:

return await client.post('/v1/login', credentials)
        .then(user => {
            console.log('user: ', user);

            return user;
        })
        .catch(function (error) {
            console.log('error: ', error);

            return error;
        });

When I provide an invalid un/pw, I am getting into the catch, and seeing the error message which is:

error: Error: Request failed with status code 400

I am failing to properly return it though. As in, the code that calls this method is always ending up in the .then and not in the .catch block.

I feel like this is a really simple thing that I'm making incredibly difficult. Thank you for your help!

like image 957
Damon Avatar asked Nov 22 '25 14:11

Damon


2 Answers

then is called when the the status is: status >= 200 && status < 300. Errors are catched in the catch method. The above code should be changed like this:

try {
    await this.$store.dispatch("user/signInWithEmailAndPassword", this.form)
        .then(response => {
            console.log('status: ', response.status);
            console.log('good to go!');
        })
        .catch(error => {
                switch (error.response.status) {
                    case 400:
                        console.log('400 error');  // not getting here
                        break;
                    case 401:
                        console.log('401 error');  // or here
                        break;
                    default:
                        console.log('some other error');  // end up here all the time
                        break;
                    }

            console.log('SignInForm.authenticate error: ', error);
        });
} catch (error) {
    console.log("SignInForm.handleSubmit catch error:", error);
}

Of course you can destruct the error and get the response directly

.catch(({ response }) => {
                switch (response.status) {

UPDATE

You should also properly return the error from the service:

return await client.post('/v1/login', credentials)
        .then(user => {
            console.log('user: ', user);

            return user;
        })
        .catch(function (error) {
            console.log('error: ', error);

            return Promise.reject(error);
        });
like image 193
Nikolay Traykov Avatar answered Nov 25 '25 11:11

Nikolay Traykov


You could add a const variable in your js getting the content of a file which returns an array of key->value and then accessing it from your js with the error message.

Example of config file:

return [
    "200" => "Todo bien",
    "201" => "Todo mal"
];

Vue file:

showItems()
{
    axios.get('shopping-cart').then(response => {

        if ( response.status != 200 ) return this.error = this.errors[response.status];
        this.items = response.data;

    }).catch(error => this.error = error);
}
like image 27
David Royo Virgili Avatar answered Nov 25 '25 10:11

David Royo Virgili