This may seem stupid, but I’m trying to get the error data when a request fails in Axios.
axios
.get('foo.example')
.then((response) => {})
.catch((error) => {
console.log(error); //Logs a string: Error: Request failed with status code 404
});
Instead of the string, is it possible to get an object with perhaps the status code and content? For example:
Object = {status: 404, reason: 'Not found', body: '404 Not found'}
asked Aug 25, 2016 at 19:13
Sebastian OlsenSebastian Olsen
10.1k9 gold badges42 silver badges89 bronze badges
What you see is the string returned by the toString
method of the error
object. (error
is not a string.)
If a response has been received from the server, the error
object will contain the response
property:
axios.get('/foo')
.catch(function (error) {
if (error.response) {
console.log(error.response.data);
console.log(error.response.status);
console.log(error.response.headers);
}
});
answered Aug 25, 2016 at 19:34
Nick UraltsevNick Uraltsev
23.7k4 gold badges24 silver badges14 bronze badges
17
With TypeScript, it is easy to find what you want with the right type.
This makes everything easier because you can get all the properties of the type with autocomplete, so you can know the proper structure of your response and error.
import { AxiosResponse, AxiosError } from 'axios'
axios.get('foo.example')
.then((response: AxiosResponse) => {
// Handle response
})
.catch((reason: AxiosError) => {
if (reason.response!.status === 400) {
// Handle 400
} else {
// Handle else
}
console.log(reason.message)
})
Also, you can pass a parameter to both types to tell what are you expecting inside response.data
like so:
import { AxiosResponse, AxiosError } from 'axios'
axios.get('foo.example')
.then((response: AxiosResponse<{user:{name:string}}>) => {
// Handle response
})
.catch((reason: AxiosError<{additionalInfo:string}>) => {
if (reason.response!.status === 400) {
// Handle 400
} else {
// Handle else
}
console.log(reason.message)
})
answered Sep 17, 2019 at 3:03
3
As @Nick said, the results you see when you console.log
a JavaScript Error
object depend on the exact implementation of console.log
, which varies and (imo) makes checking errors incredibly annoying.
If you’d like to see the full Error
object and all the information it carries bypassing the toString()
method, you could just use JSON.stringify:
axios.get('/foo')
.catch(function (error) {
console.log(JSON.stringify(error))
});
answered Feb 14, 2017 at 9:17
daniidanii
5,5132 gold badges21 silver badges23 bronze badges
2
There is a new option called validateStatus
in request config. You can use it to specify to not throw exceptions if status < 100 or status > 300 (default behavior). Example:
const {status} = axios.get('foo.example', {validateStatus: () => true})
answered Mar 31, 2020 at 12:44
You can use the spread operator (...
) to force it into a new object like this:
axios.get('foo.example')
.then((response) => {})
.catch((error) => {
console.log({...error})
})
Be aware: this will not be an instance of Error.
answered Jan 22, 2020 at 20:31
Moses SchwartzMoses Schwartz
2,7181 gold badge19 silver badges31 bronze badges
0
I am using this interceptors to get the error response.
const HttpClient = axios.create({
baseURL: env.baseUrl,
});
HttpClient.interceptors.response.use((response) => {
return response;
}, (error) => {
return Promise.resolve({ error });
});
answered Dec 5, 2016 at 16:41
TanTan
3323 silver badges11 bronze badges
2
In order to get the http status code returned from the server, you can add validateStatus: status => true
to axios options:
axios({
method: 'POST',
url: 'http://localhost:3001/users/login',
data: { username, password },
validateStatus: () => true
}).then(res => {
console.log(res.status);
});
This way, every http response resolves the promise returned from axios.
https://github.com/axios/axios#handling-errors
answered May 7, 2020 at 11:48
Emre TapcıEmre Tapcı
1,68314 silver badges15 bronze badges
Whole error can only be shown using error.response like that :
axios.get('url').catch((error) => {
if (error.response) {
console.log(error.response);
}
});
answered Jul 1, 2021 at 10:07
const handleSubmit = (e) => {
e.preventDefault();
// console.log(name);
setLoading(true);
createCategory({ name }, user.token)
.then((res) => {
// console.log("res",res);
setLoading(false);
setName("");
toast.success(`"${res.data.name}" is created`);
loadCategories();
})
.catch((err) => {
console.log(err);
setLoading(false);
if (err.response.status === 400) toast.error(err.response.data);//explained in GD
});
};
See the console log then you will understand clearly
answered Oct 7, 2022 at 4:08
With Axios
post('/stores', body).then((res) => {
notifyInfo("Store Created Successfully")
GetStore()
}).catch(function (error) {
if (error.status === 409) {
notifyError("Duplicate Location ID, Please Add another one")
} else {
notifyError(error.data.detail)
}
})
answered Sep 3, 2021 at 5:43
It’s indeed pretty weird that fetching only error does not return an object. While returning error.response gives you access to most feedback stuff you need.
I ended up using this:
axios.get(...).catch( error => { return Promise.reject(error.response.data.error); });
Which gives strictly the stuff I need: status code (404) and the text-message of the error.
answered Apr 27, 2021 at 12:14
You can put the error into an object and log the object, like this:
axios.get('foo.example')
.then((response) => {})
.catch((error) => {
console.log({error}) // this will log an empty object with an error property
});
answered Jan 22, 2020 at 21:29
MendyMendy
7,2305 gold badges28 silver badges40 bronze badges
Axios. get('foo.example')
.then((response) => {})
.catch((error) => {
if(error. response){
console.log(error. response. data)
console.log(error. response. status);
}
})
answered Jan 14, 2021 at 5:59
VigneshVignesh
1371 silver badge5 bronze badges
3
It’s my code: Work for me
var jsonData = request.body;
var jsonParsed = JSON.parse(JSON.stringify(jsonData));
// message_body = {
// "phone": "5511995001920",
// "body": "WhatsApp API on chat-api.com works good"
// }
axios.post(whatsapp_url, jsonParsed,validateStatus = true)
.then((res) => {
// console.log(`statusCode: ${res.statusCode}`)
console.log(res.data)
console.log(res.status);
// var jsonData = res.body;
// var jsonParsed = JSON.parse(JSON.stringify(jsonData));
response.json("ok")
})
.catch((error) => {
console.error(error)
response.json("error")
})
answered Jul 4, 2020 at 12:17
This may seem stupid, but I’m trying to get the error data when a request fails in Axios.
axios
.get('foo.example')
.then((response) => {})
.catch((error) => {
console.log(error); //Logs a string: Error: Request failed with status code 404
});
Instead of the string, is it possible to get an object with perhaps the status code and content? For example:
Object = {status: 404, reason: 'Not found', body: '404 Not found'}
asked Aug 25, 2016 at 19:13
Sebastian OlsenSebastian Olsen
10.1k9 gold badges42 silver badges89 bronze badges
What you see is the string returned by the toString
method of the error
object. (error
is not a string.)
If a response has been received from the server, the error
object will contain the response
property:
axios.get('/foo')
.catch(function (error) {
if (error.response) {
console.log(error.response.data);
console.log(error.response.status);
console.log(error.response.headers);
}
});
answered Aug 25, 2016 at 19:34
Nick UraltsevNick Uraltsev
23.7k4 gold badges24 silver badges14 bronze badges
17
With TypeScript, it is easy to find what you want with the right type.
This makes everything easier because you can get all the properties of the type with autocomplete, so you can know the proper structure of your response and error.
import { AxiosResponse, AxiosError } from 'axios'
axios.get('foo.example')
.then((response: AxiosResponse) => {
// Handle response
})
.catch((reason: AxiosError) => {
if (reason.response!.status === 400) {
// Handle 400
} else {
// Handle else
}
console.log(reason.message)
})
Also, you can pass a parameter to both types to tell what are you expecting inside response.data
like so:
import { AxiosResponse, AxiosError } from 'axios'
axios.get('foo.example')
.then((response: AxiosResponse<{user:{name:string}}>) => {
// Handle response
})
.catch((reason: AxiosError<{additionalInfo:string}>) => {
if (reason.response!.status === 400) {
// Handle 400
} else {
// Handle else
}
console.log(reason.message)
})
answered Sep 17, 2019 at 3:03
3
As @Nick said, the results you see when you console.log
a JavaScript Error
object depend on the exact implementation of console.log
, which varies and (imo) makes checking errors incredibly annoying.
If you’d like to see the full Error
object and all the information it carries bypassing the toString()
method, you could just use JSON.stringify:
axios.get('/foo')
.catch(function (error) {
console.log(JSON.stringify(error))
});
answered Feb 14, 2017 at 9:17
daniidanii
5,5132 gold badges21 silver badges23 bronze badges
2
There is a new option called validateStatus
in request config. You can use it to specify to not throw exceptions if status < 100 or status > 300 (default behavior). Example:
const {status} = axios.get('foo.example', {validateStatus: () => true})
answered Mar 31, 2020 at 12:44
You can use the spread operator (...
) to force it into a new object like this:
axios.get('foo.example')
.then((response) => {})
.catch((error) => {
console.log({...error})
})
Be aware: this will not be an instance of Error.
answered Jan 22, 2020 at 20:31
Moses SchwartzMoses Schwartz
2,7181 gold badge19 silver badges31 bronze badges
0
I am using this interceptors to get the error response.
const HttpClient = axios.create({
baseURL: env.baseUrl,
});
HttpClient.interceptors.response.use((response) => {
return response;
}, (error) => {
return Promise.resolve({ error });
});
answered Dec 5, 2016 at 16:41
TanTan
3323 silver badges11 bronze badges
2
In order to get the http status code returned from the server, you can add validateStatus: status => true
to axios options:
axios({
method: 'POST',
url: 'http://localhost:3001/users/login',
data: { username, password },
validateStatus: () => true
}).then(res => {
console.log(res.status);
});
This way, every http response resolves the promise returned from axios.
https://github.com/axios/axios#handling-errors
answered May 7, 2020 at 11:48
Emre TapcıEmre Tapcı
1,68314 silver badges15 bronze badges
Whole error can only be shown using error.response like that :
axios.get('url').catch((error) => {
if (error.response) {
console.log(error.response);
}
});
answered Jul 1, 2021 at 10:07
const handleSubmit = (e) => {
e.preventDefault();
// console.log(name);
setLoading(true);
createCategory({ name }, user.token)
.then((res) => {
// console.log("res",res);
setLoading(false);
setName("");
toast.success(`"${res.data.name}" is created`);
loadCategories();
})
.catch((err) => {
console.log(err);
setLoading(false);
if (err.response.status === 400) toast.error(err.response.data);//explained in GD
});
};
See the console log then you will understand clearly
answered Oct 7, 2022 at 4:08
With Axios
post('/stores', body).then((res) => {
notifyInfo("Store Created Successfully")
GetStore()
}).catch(function (error) {
if (error.status === 409) {
notifyError("Duplicate Location ID, Please Add another one")
} else {
notifyError(error.data.detail)
}
})
answered Sep 3, 2021 at 5:43
It’s indeed pretty weird that fetching only error does not return an object. While returning error.response gives you access to most feedback stuff you need.
I ended up using this:
axios.get(...).catch( error => { return Promise.reject(error.response.data.error); });
Which gives strictly the stuff I need: status code (404) and the text-message of the error.
answered Apr 27, 2021 at 12:14
You can put the error into an object and log the object, like this:
axios.get('foo.example')
.then((response) => {})
.catch((error) => {
console.log({error}) // this will log an empty object with an error property
});
answered Jan 22, 2020 at 21:29
MendyMendy
7,2305 gold badges28 silver badges40 bronze badges
Axios. get('foo.example')
.then((response) => {})
.catch((error) => {
if(error. response){
console.log(error. response. data)
console.log(error. response. status);
}
})
answered Jan 14, 2021 at 5:59
VigneshVignesh
1371 silver badge5 bronze badges
3
It’s my code: Work for me
var jsonData = request.body;
var jsonParsed = JSON.parse(JSON.stringify(jsonData));
// message_body = {
// "phone": "5511995001920",
// "body": "WhatsApp API on chat-api.com works good"
// }
axios.post(whatsapp_url, jsonParsed,validateStatus = true)
.then((res) => {
// console.log(`statusCode: ${res.statusCode}`)
console.log(res.data)
console.log(res.status);
// var jsonData = res.body;
// var jsonParsed = JSON.parse(JSON.stringify(jsonData));
response.json("ok")
})
.catch((error) => {
console.error(error)
response.json("error")
})
answered Jul 4, 2020 at 12:17
Introduction
Axios is a JavaScript library that uses the Promise API to create HTTP requests with http
in Node.js runtime or XMLHttpRequests
in the browser. Because these requests are promises, they work with the newer async/await syntax, as well as .then()
functions for promise chaining and the .catch()
mechanism for error handling.
try {
let res = await axios.get('/my-api-route');
// Work with the response...
} catch (err) {
// Handle error
console.log(err);
}
In this article, we will see how to handle errors with Axios, as this is very important when making any HTTP calls knowing fully well that there are times when the service you’re calling might not be available or return other unexpected errors. We’ll show the
.then()
/.catch()
method, but primarily use the async/await syntax.
Then and Catch
Promises can be handled in two ways using modern JS — the async/await syntax, which was shown above, as well as .then()
and .catch()
methods. Note that both of these methods can produce the same functionality, but async/await is typically regarded as being easier to work with and requires less boilerplate code in longer promise chains.
Here is how you’d achieve the same thing, but using the then/catch method:
axios.get('/my-api-route')
.then(res => {
// Work with the response...
}).catch(err => {
// Handle error
console.log(err);
});
Both the res
and err
objects are the same as with the async/await syntax.
Handling Errors
In this section, we will look at two primary categories of problems, as well as other issues that we may encounter and how to manage them using Axios. It is critical that you understand that this applies to all types of HTTP queries handled by Axios, including GET
, POST
, PATCH
, and so on.
Here you can see the syntax for the three aspects — this will capture the error; it is crucial to note that this error carries a large error object with a lot of information:
try {
let res = await axios.get('/my-api-route');
// Work with the response...
} catch (err) {
if (err.response) {
// The client was given an error response (5xx, 4xx)
} else if (err.request) {
// The client never received a response, and the request was never left
} else {
// Anything else
}
}
The differences in the error object, highlighted above in the catch
code, indicate where the request encountered the issue. We’ll look deeper into this in the following sections.
error.response
This is the type of mistake we are most familiar with, and it is much easier to deal with. Many sites display a 404 Not Found page/error message or various response codes based on what the API provides; this is often handled via the response.
If your error object has a response property, it signifies your server returned a 4xx/5xx error. This will assist you choose what sort of message to return to users; the message you’ll want to provide for 4xx may differ from that for 5xx, and if your backend isn’t returning anything at all.
try {
let res = await axios.get('/my-api-route');
// Work with the response...
} catch (err) {
if (err.response) {
// The client was given an error response (5xx, 4xx)
console.log(err.response.data);
console.log(err.response.status);
console.log(err.response.headers);
} else if (err.request) {
// The client never received a response, and the request was never left
} else {
// Anything else
}
}
error.request
This error is most commonly caused by a bad/spotty network, a hanging backend that does not respond instantly to each request, unauthorized or cross-domain requests, and lastly if the backend API returns an error.
Note: This occurs when the browser was able to initiate a request but did not receive a valid answer for any reason.
try {
let res = await axios.get('/my-api-route');
// Work with the response...
} catch (err) {
if (err.response) {
// The client was given an error response (5xx, 4xx)
} else if (err.request) {
// The client never received a response, and the request was never left
console.log(err.request);
} else {
// Anything else
}
}
Earlier we mentioned that the underlying request Axios uses depends on the environment in which it’s being run. This is also the case for the err.request
object. Here the err.request
object is an instance of XMLHttpRequest
when being executed in the browser, whereas it’s an instance of http.ClientRequest
when being used in Node.js.
Other Errors
It’s possible that the error object does not have either a response
or request
object attached to it. In this case it is implied that there was an issue in setting up the request, which eventually triggered an error.
try {
let res = await axios.get('/my-api-route');
// Work with the response...
} catch (err) {
if (err.response) {
// The client was given an error response (5xx, 4xx)
} else if (err.request) {
// The client never received a response, and the request was never left
} else {
// Anything else
console.log('Error', err.message);
}
}
For example, this could be the case if you omit the URL parameter from the .get()
call, and thus no request was ever made.
Conclusion
In this short article, we looked at how we may handle various sorts of failures and errors in Axios. This is also important for giving the correct message to your application/website visitors, rather than always returning a generic error message, sending a 404, or indicating network problems.
- Introduction
- Error Objects
- Error Lists
- Responses
- HTTP Status
- JSON:API Exceptions
- Helper Methods
- Validation Errors
- Source Pointers
- Error Rendering
- JSON Responses
- Middleware Responses
- Always Rendering JSON:API Errors
- Custom Rendering Logic
- Converting Exceptions
- Error Reporting
# Introduction
The JSON:API specification defines error objects (opens new window)
that are used to provide information to a client about problems encountered
while performing an operation.
Errors are returned to the client in the top-level errors
member of the
JSON document.
Laravel JSON:API makes it easy to return errors to the client — either
as responses, or by throwing exceptions. In addition, the exception
renderer you added to your exception handler during
installation takes care of
converting standard Laravel exceptions to JSON:API error responses
if the client has sent an Accept: application/vnd.api+json
header.
# Error Objects
Use our LaravelJsonApiCoreDocumentError
object to create a JSON:API
error object. The easiest way to construct an error object is using the
static fromArray
method. For example:
The fromArray
method accepts all the error object members
defined in the specification. (opens new window)
Alternatively, if you want to use setters, use the static make
method
to fluently construct your error object:
The available setters are:
setAboutLink
setCode
setDetail
setId
setLinks
setMeta
setStatus
setSource
setSourceParameter
setSourcePointer
setTitle
# Error Lists
If you need to return multiple errors at once, use our
LaravelJsonApiCoreDocumentErrorList
class. This accepts any number
of error objects to its constructor. For example:
Use the push
method to add errors after constructing the error list:
# Responses
Both the Error
and ErrorList
classes implement Laravel’s Responsable
interface. This means you can return them directly from controller actions
and they will be converted to a JSON:API error response.
If you need to customise the error response, then you need to use our
LaravelJsonApiCoreResponsesErrorResponse
class. Either create
a new one, passing in the Error
or ErrorList
object:
Or alternatively, use the prepareResponse
method on either the Error
or ErrorList
object:
The ErrorResponse
class has all the helper methods
required to customise both the headers and the JSON:API document that
is returned in the response.
For example, if we were adding a header and meta to our response:
# HTTP Status
The JSON:API specification says:
When a server encounters multiple problems for a single request,
the most generally applicable HTTP error code SHOULD be used in the response.
For instance,400 Bad Request
might be appropriate for multiple 4xx errors
or500 Internal Server Error
might be appropriate for multiple 5xx errors.
Our ErrorResponse
class takes care of calculating the HTTP status for you.
If there is only one error, or all the errors have the same status, then
the response status will match this status.
If you have multiple errors with different statuses, the response status
will be 400 Bad Request
if the error objects only have 4xx
status codes.
If there are any 5xx
status codes, the response status will be
500 Internal Server Error
.
If the response has no error objects, or none of the error objects have a
status, then the response will have a 500 Internal Server Error
status.
If you want the response to have a specific HTTP status, use the
withStatus
method. For example:
# JSON:API Exceptions
Our LaravelJsonApiCoreExceptionsJsonApiException
allows you to terminate
processing of a request by throwing an exception with JSON:API errors
attached.
The exception expects its first argument to be either an Error
or an
ErrorList
object. For example:
The JsonApiException
class has all the helper methods
required to customise both the headers and the JSON:API document that
is returned in the response. Use the static make
method if you need to
call any of these methods. For example:
There is also a handy static error
method. This allows you to fluently
construct an exception for a single error, providing either an Error
object or an array. For example:
# Helper Methods
The JsonApiException
class has a number of helper methods:
- is4xx
- is5xx
- getErrors
# is4xx
Returns true
if the HTTP status code is a client error, i.e. in the 400-499
range.
# is5xx
Returns true
if the HTTP status code is a server error, i.e. in the 500-599
range.
# getErrors
Use the getErrors()
method to retrieve the JSON:API error objects from the
exception. For example, if we wanted to log the errors:
# Validation Errors
Our implementation of resource requests and
query parameter requests already takes
care of converting Laravel validation error messages to JSON:API errors.
If however you have a scenario where you want to convert a failed validator
to JSON:API errors manually, we provide the ability to do this.
You will need to resolve an instance of LaravelJsonApiValidationFactory
out of the service container. For example, you could use the app
helper,
or use dependency injection by type-hinting it in a constructor of a service.
Once you have the factory instance, use the createErrors
method,
providing it with the validator instance. For example, in a controller
action:
The object this returns is Responsable
— so you can return it directly
from a controller action. If you want to convert it to an error response,
use our prepareResponse
pattern as follows:
# Source Pointers
By default this process will convert validation error keys to JSON source
pointers. For example, if you have a failed message for the foo.bar
value, the resulting error object will have a source pointer of
/foo/bar
.
If you need to prefix the pointer value, use the withSourcePrefix
method.
The following example would convert foo.bar
to /data/attributes/foo/bar
:
If you need to fully customise how the validation key should be converted,
provide a Closure
to the withPointers
method:
# Error Rendering
As described in the installation instructions,
the following should have been added to the register
method on your
application’s exception handler:
The Laravel exception handler already takes care of converting exceptions to
either application/json
or text/html
responses. Our exception handler
effectively adds JSON:API error responses as a third media type. If the
client has sent a request with an Accept
header of application/vnd.api+json
,
then they will receive the exception response as a JSON:API error response —
even if the endpoint they are hitting is not one of your JSON:API server
endpoints.
WARNING
There are some scenarios where the Laravel exception handler does not call
any registered renderables. For example, if an exception implements Laravel’s
Responsable
interface, our exception parser will not be invoked as the handler
uses the Responsable::toResponse()
method on the exception to generate a
response.
# JSON Responses
If a client encounters an exception when using an Accept
header of
application/json
, they will still receive Laravel’s default JSON exception
response, rather than a JSON:API response.
If you want our exception parser to render JSON exception responses instead
of the default Laravel response, use the acceptsJson()
method when registering
our exception parser:
# Middleware Responses
Sometimes you may want exceptions to be converted to JSON:API errors if the
current route has a particular middleware applied to it. The most common example
of this would be if you want JSON:API errors to always be rendered if the
current route has the api
middleware.
In this scenario, use the acceptsMiddleware()
method when registering our
exception parser. For example:
TIP
You can provide multiple middleware names to the acceptsMiddleware()
method.
When you do this, it will match a route that contains any of the provided
middleware.
# Always Rendering JSON:API Errors
If you want our exception parser to always convert exceptions to JSON:API
errors, use the acceptsAll()
helper method:
# Custom Rendering Logic
If you want your own logic for when a JSON:API exception response should be
rendered, pass a closure to the accept()
method.
For example, let’s say we wanted our API to always return JSON:API exception
responses, regardless of what Accept
header the client sent. We would use
the request is()
method to check if the path is our API:
TIP
If you return false
from the callback, the normal exception rendering logic
will run — meaning a client that has sent an Accept
header with the JSON:API
media type will still receive a JSON:API response. This is semantically correct,
as the Accept
header value should be respected.
# Converting Exceptions
Our exception parser is built so that you can easily add support for
custom exceptions to the JSON:API rendering process. The implementation works
using a pipeline, meaning you can add your own handlers for converting
exceptions to JSON:API errors.
For example, imagine our application had a PaymentFailed
exception, that
we wanted to convert to JSON:API errors if thrown to the exception handler.
We would write the following class:
We can then add it to the JSON:API exception parser using either the
prepend
or append
method:
# Error Reporting
As described in the installation instructions,
the following should have been added to the $dontReport
property on your
application’s exception handler:
This prevents our JsonApiException
from being reported in your application’s
error log. This is a sensible starting position, as the JsonApiException
class is effectively a HTTP exception that needs to be rendered to the client.
However, this does mean that any JsonApiException
that has a 5xx
status
code (server-side error) will not be reported in your error log. Therefore,
an alternative is to use the helper methods on the JsonApiException
class
to determine whether or not the exception should be reported.
To do this, we will use the reportable()
method to register a callback
for the JSON:API exception class. (At the same time, we remove the exception
class from the $dontReport
property.) For example, the following will stop
the propagation of JSON:API exceptions to the default logging stack if the
exception does not have a 5xx status:
In the following example, we log 4xx statuses as debug information, while
letting all other JSON:API exceptions propagate to the default logging stack: