当向API发送一个太大的文件时,我会得到:

Error: write EPIPE
    at WriteWrap.onWriteComplete [as oncomplete] (node:internal/stream_base_commons:94:16) {
  errno: -32,
  code: 'EPIPE',
  syscall: 'write'
}

服务器停止接收流并给出代码413.我的应用程序崩溃忽略任何try catch块.据我所知,这是无法try 捕捉的.有没有其他的方法来处理axios的这些错误? 下面是我的代码:

import axios from "axios"
import { sleep } from "./utils/sleep"

export const debugEpipe = async (event) => {
  // Fake a big file
  const fileSizeInMb = event.fileSizeInMb
  const fileContent = Buffer.alloc(fileSizeInMb * 1024 * 1024, 'a')
    .toString('base64')

  try {
    const response = await axios.post(
      '/some-endpoint',
      {
        attachments: [
          {
            filename: 'bigfakefile.pdf',
            filetype: 'application/pdf',
            data: fileContent,
          }
        ],
      }
    )
  } catch(e) {
    console.log("This will show.")
    await sleep(1000)
    console.log("This will not show. The EPIPE error halts execution.")
  }
}

推荐答案

当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拦截器的控制范围之内.

Node.js相关问答推荐

promise 所有映射或反对

我的位置也移动时左右拖动谷歌 map

即使DDB键不存在, node Lambda也不会失败,并返回NULL作为结果

Mongoose更新许多不使用数组作为筛选器来更新记录

如何在Mongoose中调用动态Collection ?

Node-Red Tasmota 错误:连接 ECONNREFUSED 192.168.77.21:1883

Playwright - 无法在 img 标签中使用 file:// 访问本地文件

一个大型的单个 Redis 实例可以处理所有事情,还是多个 Redis 实例?

无法使用 Express 设置会话 cookie 的过期日期

Axios TypeError:将循环 struct 转换为 JSON

MongoDB Aggregate - 如何使用前一阶段的值作为下一阶段的字段名称?

Zod 模式中的self 数组

ESLint:TypeError:this.libOptions.parse 不是函数

部署云功能 Firebase/Stripe 时出错

使用中的端口代码:'EADDRINUSE',即使在 kill 命令之后

Web3.js 脚本在监听 CreatedPairs 时退出

如何将使用 Gulp 的 node 部署到 heroku

Node.js + Express + Handlebars.js + 局部视图

如何从命令行在 Node.js 上运行 Jasmine 测试

node.js 异步库