Enhanced Error Information
# Enhanced Error Information
# Requirements Analysis
In the previous lesson, we captured several types of AJAX errors, but the error information provided is very limited. We want the externally-provided information to include not just error text, but also the request configuration object config, error code code, the XMLHttpRequest object instance request, and the custom response object response.
axios({
method: 'get',
url: '/error/timeout',
timeout: 2000
}).then((res) => {
console.log(res)
}).catch((e: AxiosError) => {
console.log(e.message)
console.log(e.request)
console.log(e.code)
})
2
3
4
5
6
7
8
9
10
11
This way, application developers can capture detailed error information for further processing.
Next, let's enhance the error information.
# Creating the AxiosError Class
First, let's define the AxiosError type interface for external use.
types/index.ts:
export interface AxiosError extends Error {
config: AxiosRequestConfig
code?: string
request?: any
response?: AxiosResponse
isAxiosError: boolean
}
2
3
4
5
6
7
Then we create an error.ts file and implement the AxiosError class, which extends the Error class.
helpers/error.ts:
import { AxiosRequestConfig, AxiosResponse } from '../types'
export class AxiosError extends Error {
isAxiosError: boolean
config: AxiosRequestConfig
code?: string | null
request?: any
response?: AxiosResponse
constructor(
message: string,
config: AxiosRequestConfig,
code?: string | null,
request?: any,
response?: AxiosResponse
) {
super(message)
this.config = config
this.code = code
this.request = request
this.response = response
this.isAxiosError = true
Object.setPrototypeOf(this, AxiosError.prototype)
}
}
export function createError(
message: string,
config: AxiosRequestConfig,
code?: string | null,
request?: any,
response?: AxiosResponse
): AxiosError {
const error = new AxiosError(message, config, code, request, response)
return error
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
AxiosError extends Error and adds its own properties: config, code, request, response, isAxiosError, etc. Note the use of Object.setPrototypeOf(this, AxiosError.prototype) -- this is needed to work around a TypeScript issue (opens new window) when extending built-in objects.
Additionally, we expose a createError factory method for convenience.
# Applying the createError Method
Modify the error object creation logic as follows:
xhr.ts:
import { createError } from './helpers/error'
request.onerror = function handleError() {
reject(createError(
'Network Error',
config,
null,
request
))
}
request.ontimeout = function handleTimeout() {
reject(createError(
`Timeout of ${config.timeout} ms exceeded`,
config,
'ECONNABORTED',
request
))
}
function handleResponse(response: AxiosResponse) {
if (response.status >= 200 && response.status < 300) {
resolve(response)
} else {
reject(createError(
`Request failed with status code ${response.status}`,
config,
null,
request,
response
))
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
# Exporting Type Definitions
In the demo, TypeScript can't infer the e parameter as AxiosError type, so we need to manually specify the type. To allow external applications to import the AxiosError type, we need to export it.
We create an axios.ts file and copy the code from index.ts to it, then modify index.ts.
index.ts:
import axios from './axios'
export * from './types'
export default axios
2
3
4
5
Now we can import the AxiosError type in our demo.
examples/error/app.ts:
import axios, { AxiosError } from '../../src/index'
axios({
method: 'get',
url: '/error/timeout',
timeout: 2000
}).then((res) => {
console.log(res)
}).catch((e: AxiosError) => {
console.log(e.message)
console.log(e.code)
})
2
3
4
5
6
7
8
9
10
11
12
This concludes our error handling for ts-axios. In the next chapter, we'll extend the ts-axios interface to provide more convenient and useful APIs.