Unable to access returned error response in Axios from Laravel Lumen API - laravel

I've got a Laravel Lumen 7 RESTful API alongside a Nuxt JS front-end with Axios. My front-end makes Axios calls to the API and inside of my Lumen project I'm of course returning relevant responses and error codes. However, it appears that these responses although I can see them when I inspect the network and can see it in the preview/response tabs, I'm unable to access it from Axios in my catch() block...
If I change it to a 200 response then I can access it from my then() block but this isn't ideal.
Lumen response
return response()->json(['success' => false, 'message' => 'We\'re unable to add this domain right now, please try again shortly'], 500);
JS Axios function
/*
** Add domain
*/
addDomain () {
// add new domain
this.$axios.post(`${process.env.API_URL}/api/domains/add`, this.domainCreation).then(res => {
console.log(res)
}).catch(err => {
console.log(err) // doesn't display my Object from laravel, instead just the native error string: "Error: Request failed with status code 500"
})
}
Can anyone help?

try this err.response catch error data is inside response
this.$axios.post(`${process.env.API_URL}/api/domains/add`, this.domainCreation).then(res => {
console.log(res)
}).catch(err => {
console.log(err.response);
})
ref link https://github.com/axios/axios#handling-errors

In addition to the above answer, you should consider returning the correct response codes.
5xx error codes are for Internal Server Errors. You are probably looking to return a 422 unprocessable entity error.
More info about 500 status code: https://httpstatuses.com/500
More info about 422 status code: https://httpstatuses.com/422

Related

(VueJS, Axios) Different way to catch errors

I'm currently building a single page application based on Laravel and VueJS.
Is there any better way then mine to handle errors with axios?
This is how I currently do it when a user clicks on login button:
VueTemplae:
methods : {
authenticateUser() {
axios.post('/api/login', this.form).then(() => {
this.$router.push({name : 'home'});
}).catch((error) => {
this.error = error.response.data.message;
});
}
}
Api route:
public function login() {
try {
// do validation
} catch(Exception) {
// validation failed
throw new Exception('login.failed');
}
// manually authentication
if(Auth::attempt(request()->only('email', 'password'))) {
return response()->json(Auth::user(), 200);
}
// something else went wrong
throw new Exception('login.failed');
}
Unfortunately, throwing an exception always prints an internal server error into the console.
If I return something else than an exception, axios always executes then().
Is there any way to prevent this or a better way to handle axios responses?
Thank you!
Your API needs to return a response with a 4XX status code in order for the catch block to fire in your Vue component.
Example:
After you catch the error on the API side, send a response with status code 400 Bad Request. It will be formatted similarly to your successful login response, but with an error message and 400 status code instead of 200.

How do I get a specific column name values using Axios Promise-based Http Request in Vue.js and Laravel 8

If I do this in my Vue.js script component
getResumeAPIData(id){
// declare a response interceptor
axios.interceptors.response.use((response) => {
// do something with the response data
console.log('Response was received');
return response;
}, error => {
// handle the response error
return Promise.reject(error);
});
// sent a GET request
axios.get(`api/resume-data-returns/${id}`)
.then((response)=>{
this.RelationTable = response.data
console.log(this.RelationTable);
})
},
I get a response like this
{"id":1,"name":"userlocalvm","email":"userlocalvm#v","email_verified_at":null,"type":"user","bio":"Why","photo":"1606931001.jpeg","created_at":"2020-12-02T16:01:00.000000Z","updated_at":"2020-12-02T17:43:21.000000Z"}
Because of my Laravel api.php->Controller Backend code
$findOrFailId = Resumes::findOrFail($forEachId);
$foreignKeyOfResTable = $findOrFailId->user_id;
return User::findOrFail($foreignKeyOfResTable);
But if I do it like this as
// sent a GET request
axios.get(`api/resume-data-returns/${id}`)
.then((response)=>{
this.RelationTable = response.data.created_at
console.log(this.RelationTable);
})
The added dot then the property name of the column
response.data.created_at
I get a response
undefined
Sorry if this is a silly question as I am still quite a rookie in programming in general and the jargons that comes with it and I want learn and master javascript and php so bad!
It might be that the response is inside another data object. You might have to do something like this:
response.data.data.created_at

TypeError: Cannot read property 'status' of undefined when receiving errors from Laravel validation

I'm trying to validate a form via AJAX using Axios with vue.
axios.post('api/registro', this.sede)
.then(response => {
this.$emit('cerrar')
})
.catch(err => {
console.log(err)
})
The error comes from the catch part, as it's coming from a Laravel validator. The response from the server is 422 and it contains a JSON with a message and the errors the server is sending.
Everything works fine if I dont try to log the error.
The problem was coming from me using interceptors in axios, I wasn't returning the errors in the interceptors properly, so nothing was coming into the catch function.
This is what I had:
axios.interceptors.response.use(null, function (error) {
// some logic
});
And this is how it should've been:
axios.interceptors.response.use(null, function (error) {
// some logic
return Promise.reject(error);
});
Thank you all so much for your help.
You can just check for errors like so:
if(err.response.data.errors){
this.errors = err.response.data.errors;
}
this.errors would be an array you can loop through using v-for to display it

Angular 2 HttpClient error body

I'm using the new (4.3) HttpClient in angular to POST data to my backend server:
this.httpClient.post<View>(`/path`, data).subscribe(
(view: View) => console.log("Success"),
(error: HttpErrorResponse) => {
console.log(error)
this.errorMessage = <any>error.error;
});
);
This call generates an (expected) error (409), but for some reason, the logged error does not contain the body of the error sent from the server. I can see the status code, but the error.error field, which should contain the response body is missing. Anyone have any ideas what could be wrong?
I've tested the backend call using curl, and can see the response body from the server.
Is your error body coming back as JSON or un-formatted text/other? I had a similar problem until i realized the body returned with the error result was a simple string. I had to change the call to something similar to this (forgive the lack of type-safety here):
this.http.post('http://address', body, { responseType: 'text' })
.subscribe(data => {
this.result = data['value'];
this.router.navigate(['/route']);
}, (error: HttpErrorResponse) => {
this.error = error.error;
this.router.navigate(['/error']);
});
This is a known bug in angular which is throwing an exception during the json parsing and not populating the error field:
https://github.com/angular/angular/pull/18466

Can't access laravel response from ajax library

// Edit: Hm...this is an firebug bug in firefox. On chrome it works...
I'm using Laravel 5.3 with Vue 2.0 and the axios ajax library.
Here is a test controller, where i return a response from laravel:
public function testMethod() {
return response('this is an error', 500);
}
Here is my ajax call:
http(`fetch-data`).then(response => {
const data = response.data;
console.log(data);
}).catch(error => {
console.log(error); // <- This doens't work, he show my nothing
alert(error);
});
The problem is, i need the error message which is returned from laravel into my client catch. But if i console.log them, he show me nothing. If i alert the error, he gives me the following message: Error: Request failed with status code 500.
Why can't i access something like error.statusCode, error.statusMessage?
Try
return response()->json('this is an error', 500);

Resources