当Node.js进程试图写入另一端已关闭的流时,就会出现EPIPE
error:在本例中,服务器判断有效载荷太大并关闭连接.
您需要在Node.js应用程序的不同级别上实现错误处理机制,以处理使用Axios并期待类似413 status code (Payload Too Large
)的响应时出现的EPIPE
错误.
由于Axios为promise-based,因此使用TRY/CATCH块捕获错误应该适用于大多数与HTTP相关的错误.
However, since EPIPE
is a system-level error, it might not always be caught by the promise-based error handling in Axios (try/catch
or .then().catch()
): it can occur outside the lifecycle of the HTTP request as managed by Axios.
To make sure your application can handle such errors gracefully, you can implement global error handling in Node.js, capturing unhandled exceptions and unhandled promise rejections at the process level:
process.on('uncaughtException', (error) => {
console.error('Unhandled Exception:', error);
});
process.on('unhandledRejection', (reason, promise) => {
console.error('Unhandled Rejection:', reason);
});
Axios interceptor可以用于集中管理HTTP请求错误,包括在到达.catch()
块或在async/await
上下文中抛出之前重试逻辑或错误转换:
axios.interceptors.response.use(response => {
// Handle successful response
return response;
}, error => {
console.error("Intercepted error:", error);
// Handle error
// Optionally, tailor handling based on error specifics
return Promise.reject(error);
});
这不会阻止EPIPE
个错误,但确保您的应用程序可以记录它们并继续运行而不会崩溃.
完整的代码为:
import axios from 'axios';
import { sleep } from './utils/sleep';
const axiosInstance = axios.create();
// Add a response interceptor
axiosInstance.interceptors.response.use(
function (response) {
// Any status code that lie within the range of 2xx cause this function to trigger
// Do something with response data
return response;
}, function (error) {
// Any status codes that falls outside the range of 2xx cause this function to trigger
// Do something with response error
console.error('Axios response error:', error);
return Promise.reject(error);
}
);
// Add a request interceptor
axiosInstance.interceptors.request.use(
function (config) {
// Do something before request is sent
console.log('Sending request to:', config.url);
return config;
}, function (error) {
// Do something with request error
console.error('Axios request error:', error);
return Promise.reject(error);
}
);
export const debugEpipe = async (event) => {
const fileSizeInMb = event.fileSizeInMb;
const fileContent = Buffer.alloc(fileSizeInMb * 1024 * 1024, 'a').toString('base64');
try {
const response = await axiosInstance.post(
'/some-endpoint',
{
attachments: [
{
filename: 'bigfakefile.pdf',
filetype: 'application/pdf',
data: fileContent,
}
],
}
);
console.log('Response status:', response.status);
} catch (e) {
console.error("Local error caught:", e);
await sleep(1000);
}
};
// Global error handling
process.on('uncaughtException', (error) => {
console.error('Unhandled Exception:', error);
});
process.on('unhandledRejection', (reason, promise) => {
console.error('Unhandled Rejection:', reason);
});
代码为Axios实例定义了请求和响应拦截器.
- 请求拦截器在发出请求之前记录请求所发送到的URL.
- 响应拦截器记录处理响应期间发生的错误.这些拦截器提供了钩子,用于在配置的Axios实例的所有使用中全局处理或记录请求和响应.
对于使用await axiosInstance.post(...)
发出的每个请求,一个try/catch
块用于处理特定于该请求的错误.这允许您处理可能特定于该请求的逻辑或上下文的错误,例如以不同的方式处理不同类型的HTTP响应错误.
它还包括针对未捕获的异常和未处理的promise 拒绝的全局错误处理程序.这些处理程序确保您的应用程序可以记录错误并对这些错误做出react ,这些错误可能与Axios请求没有直接关系,或者不在本地try/catch
块和Axios拦截器的控制范围之内.