Axios Interceptor Error handling Typescript
▌Introduction
Axios
is the Promise based HTTP client, and is often used in my Vue.js projects.
This article shows how to integrate the custom error to
handle non-2XX response and timeout request, so that we can show
customized message for end-user, not the real error.
However, they can be apply to other Http Client framework, and
of course, write the code in Javascript.
|
▋Related articles
▌Environment
▋axios 0.19.0
▋typescript 3.2.1
▌Implement
▋(Optional) Set default valid Http Status Codes
The default valid Http Status Codes are >= 200
and < 300.
That means the response with status 200~299 will NOT
be rejected by Axios.
You can change the default value by setting axios.defaults.validateStatus,
For example, the 498 response will not be rejected
by Axios with the following
configuration:
import axios, { AxiosRequestConfig,
AxiosInstance, AxiosResponse } from 'axios';
const instance = axios.create();
// Overwrite the ValidateStatus settings
instance.defaults.validateStatus = (status: number) => {
return (status
>= 200 && status < 300) || status
== 498;
};
export default instance;
▋Error handling for rejected Http response
We can create custom error class with custom (and international!)
error message for certain rejected response.
▋MyCustomError.ts
export default class
MyCustomError extends Error {
public url:
string;
public statusCode:
number | undefined;
constructor(message?:
string, url?: string, status?: number) {
super(message);
this.name = 'MyCustomError';
this.url =
String(url);
this.statusCode
= status;
this.stack = new
Error().stack;
}
/**
* Error msg for
server side
* @memberof
HttpRequestError
*/
public
toServerString = (): string => {
return `[${this.name}][${this.statusCode
|| '??'}][${this.url}] ${this.message}`;
}
/**
* Error msg for
end-user
* @memberof
HttpRequestError
*/
public toString =
(): string => {
return i18n.tc('error.httpRequestError');
}
}
Notice that we separate the client-side error
message from the server-side message because we don’t want the end-user to get
the error’s detail J
▋Error handling for rejected Http response
import axios, { AxiosRequestConfig,
AxiosInstance, AxiosResponse } from 'axios';
import JL from '@/modules/jsnlogger';
import store from '@/store';
import { MyCustomError } from '../error-model';
const instance = axios.create();
instance.interceptors.response.use( (response:
AxiosResponse<any>) => {
return response;
}, async (error: any) => {
const { config,
response: { status } } = error;
const
originalRequest = config;
const url =
originalRequest.url;
// Error
handling here ...
// For
example, use JsnLog to save server-side log on server side
const httpErr = new
HttpRequestError(error, url, status);
JL.error(httpErr.toServerString());
// Reject
the error
return
Promise.reject(httpErr);
});
export default instance;
With the above Axios instance, we can easily to
catch the custom error and show the custom client-side’s error message as
following,
try {
const url = 'api/xxxx';
const res: any = await
axios.get(url);
return res.data;
} catch (err) {
console.log(String(err));
// This will shows the custom client-side msg
}
For example, zh-TW:
en-US:
▋Error handling for Timeout request
Axios has default timeout as 0 (no timeout).
We can change the default timeout as following,
const instance = axios.create();
instance.defaults.timeout = 3000; // Million
seconds
Or by interceptor…
instance.interceptors.request.use(
(config: AxiosRequestConfig) => {
config.timeout = 3000;
// Million seconds
return config;
}, (error) => {
return
Promise.reject(error);
});
We can create another custom
error model: MyTimeoutError (just
like MyCustomError), to
handle the timeout error.
Then we can update the Axios
interceoptor:
instance.interceptors.response.use( (response:
AxiosResponse<any>) => {
return response;
}, async (error: any) => {
if (error.code
=== 'ECONNABORTED') { // Timeout error
const timeoutErr
= new MyTimeoutError(error, error.config.url);
// Do
something…
return
Promise.reject(timeoutErr);
} else {
// Handle
other err with MyCustomError model ...
}
});
▋Source code
▋Conclusion
The interceptor allows us
to handle and control corresponding error on different responses or scenarios.
So that we can focus on
the presentation or business logics when sending a Http request.
▌Reference
沒有留言:
張貼留言