In our codebase, we have a utility function that wraps the axios
http call. Currently, it is written in the form of currying with chained promises like this:
request<T>(request: AxiosRequestConfig, x: number, y: string, z: boolean): Promise<T> {
return someFunction1(x)
.then(someFunction2(y))
.then(sendRequest(z))
.catch((err) => { // handle error });
}
function someFunction1(x: number): Promise<string> { }
function someFunction2(y: string): (s: string) => Promise<AxiosRequestConfig> {}
function sendRequest(z: boolean): (req: AxiosRequestConfig) => Promise<T> {
// do other things...
return axios.request<T>(req)
.then(processResponse);
}
function processResponse(): (res: AxiosResponse<T>) => T {
// do other things...
// do something with the res.
}
To implement this, you can simply use
await request(someReq, 1, 'hello', false)
. While this approach works fine, I now intend to convert it into async/await format as I want to inject a wrapper on the sendRequest
function to include additional logic. Here is my attempt at conversion:
// The sendRequest function now returns a normal promise instead of a function.
function sendRequest<T>(z: boolean, req: AxiosRequestCofig): Promise<T> {
// do other things...
return axios.request<T>(req)
.then(processResponse);
}
// Define a function type
type RealRequestCall<T> = (z: boolean, req: AxiosRequestConfig) => Promise<T>;
// Implement the wrapper
async function requestWrapper(z: boolean, req: AxiosRequestConfig, realRequest: RealRequestCall<T>): Promise<T> {
if (!z) {
// Simply forwards the request to the real request call.
return realRequest(z, req).then(res => res);
} else {
const realResponse = await realRequestCall(z, req);
// Manipulate the response here
return Promise.resolve(realResponse);
}
}
// The new request function now utilizes requestWrapper
function request<T>(request: AxiosRequestConfig, x: number, y: string, z: boolean): Promise<T> {
return someFunction1(x)
.then(someFunction2(y))
.then(req => requestWrapper(z, req, sendRequest),
(err) => { // handle error });
}
However, when testing this implementation, I encountered two axios errors:
- Cannot set header after it's sent to client
- TypeError: Cannot read property 'processResponse' of undefined\n at sendRequest (/dist/util/http.util.js:102:24)\n at Object. (/dist/util/configProxy.js:20:20)
I am puzzled by these errors - what might be causing them during the conversion process?