【问题标题】:Maximum call stack size exceeded on GraphQL Upload with NestJS使用 NestJS 上传 GraphQL 时超出了最大调用堆栈大小
【发布时间】:2021-10-08 19:33:30
【问题描述】:

我在使用 ReadStream 函数通过 GraphQL Upload 上传文件时遇到错误:

error: 17:10:32.466+02:00 [ExceptionsHandler] Maximum call stack size exceeded
error: 17:10:32.467+02:00 [graphql] Maximum call stack size exceeded RangeError: Maximum call stack size exceeded
    at ReadStream.open (/Users/xxxx/Documents/Xxxx/xxxxx/xxxxx-api/node_modules/fs-capacitor/lib/index.js:80:7)
    at _openReadFs (internal/fs/streams.js:117:12)
    at ReadStream.<anonymous> (internal/fs/streams.js:110:3)
    at ReadStream.deprecated [as open] (internal/util.js:96:15)
    at ReadStream.open (/Users/xxxx/Documents/Xxxxx/xxxx/xxxxx-api/node_modules/fs-capacitor/lib/index.js:90:11)
    at _openReadFs (internal/fs/streams.js:117:12)
    at ReadStream.<anonymous> (internal/fs/streams.js:110:3)
    at ReadStream.deprecated [as open] (internal/util.js:96:15)
    at ReadStream.open (/Users/xxxx/Documents/Xxxxx/xxxxx/xxxxx-api/node_modules/fs-capacitor/lib/index.js:90:11)
    at _openReadFs (internal/fs/streams.js:117:12) {"stack":"RangeError: Maximum call stack size exceeded\n    at ReadStream.open (/Users/xxxx/Documents/Xxxxxx/xxxxx/xxxx-api/node_modules/fs-capacitor/lib/index.js:80:7)\n    at _openReadFs (internal/fs/streams.js:117:12)\n    at ReadStream.<anonymous> (internal/fs/streams.js:110:3)\n    at ReadStream.deprecated [as open] (internal/util.js:96:15)\n    at ReadStream.open (/Users/xxxxx/Documents/Xxxxx/xxxxx/xxxxx-api/node_modules/fs-capacitor/lib/index.js:90:11)\n    at _openReadFs (internal/fs/streams.js:117:12)\n    at ReadStream.<anonymous> (internal/fs/streams.js:110:3)\n    at ReadStream.deprecated [as open] (internal/util.js:96:15)\n    at ReadStream.open (/Users/xxxx/Documents/Xxxxxx/xxxx/xxxxx-api/node_modules/fs-capacitor/lib/index.js:90:11)\n    at _openReadFs (internal/fs/streams.js:117:12)"}
(node:44569) [DEP0135] DeprecationWarning: ReadStream.prototype.open() is deprecated
(Use `node --trace-deprecation ...` to show where the warning was created)

这是我用来上传文件的函数:

public async cleanUpload(upload: GraphqlUpload, oldName?: string) {
    let uploadResponse: FileInfo;
    try {
      if (oldName) {
        this.safeRemove(oldName);
      }
      uploadResponse = await this.uploadFile(
        {
          fileName: upload.filename,
          stream: upload.createReadStream(),
          mimetype: upload.mimetype,
        },
        { isPublic: true, filter: imageFilterFunction },
      );
      return uploadResponse;
    } catch (e) {
      this.logger.error('unable to upload', e);
      if (uploadResponse) {
        this.safeRemove(uploadResponse.fileName);
      }
      throw e;
    }
  }

【问题讨论】:

    标签: graphql upload nestjs


    【解决方案1】:

    解决方案是将Node版本14.17降级到12.18

    【讨论】:

      【解决方案2】:

      要继续使用 Node 14.17,你可以做的是禁用 Apollo 的内部上传并使用graphql-upload

      请参阅this comment,其中概述了此处引用的方法。

      对于任何未来的读者,这里是一劳永逸地解决问题的方法。

      问题在于 @nestjs/graphql 的依赖项 apollo-server-core 依赖于旧版本的 graphql-upload (v8.0),它与较新版本的 Node.js 和各种包发生冲突。 Apollo Server v2.21.0 seems to have fixed this 但@nestjs/graphql 仍在 v2.16.1 上。此外,Apollo Server v3 将是removing the built-in graphql-upload

      解决方案suggested in this comment 是禁用 Apollo Server 的内置上传处理并使用您自己的。这可以通过 3 个简单的步骤完成:

      1。包.json

      如果您添加了 fs-capacitor 和 graphql-upload 条目,请从解决方案部分删除它们,并安装最新版本的 graphql-upload(此时为 v11.0.0)包作为依赖项。

      2。 src/app.module.ts

      禁用 Apollo Server 的内置上传处理并将 graphqlUploadExpress 中间件添加到您的应用程序。

      import { graphqlUploadExpress } from "graphql-upload"
      import { MiddlewareConsumer, Module, NestModule } from "@nestjs/common"
      
      @Module({
        imports: [
          GraphQLModule.forRoot({
            uploads: false, // disable built-in upload handling
          }),
        ],
      })
      export class AppModule implements NestModule {
        configure(consumer: MiddlewareConsumer) {
          consumer.apply(graphqlUploadExpress()).forRoutes("graphql")
        }
      }
      

      3。 src/blog/post.resolver.ts(示例解析器)

      从 apollo-server-core 中移除 GraphQLUpload 导入,改为从 graphql-upload 导入

      // import { GraphQLUpload } from "apollo-server-core" <-- remove this
      import { FileUpload, GraphQLUpload } from "graphql-upload"
      
      @Mutation(() => Post)
      async postCreate(
        @Args("title") title: string,
        @Args("body") body: string,
        @Args("attachment", { type: () => GraphQLUpload }) attachment: Promise<FileUpload>,
      ) {
        const { filename, mimetype, encoding, createReadStream } = await attachment
        console.log("attachment:", filename, mimetype, encoding)
      
        const stream = createReadStream()
        stream.on("data", (chunk: Buffer) => /* do stuff with data here */)
      }
      

      【讨论】:

      • 在这种情况下我已经在使用 GraphQL Upload。
      • 您是否禁用了 apollo 的内部上传?我引用和链接的指令将允许您使用节点 14 而无需降级到节点 12。我已在节点 14 上的项目中使用它
      猜你喜欢
      • 2016-09-26
      • 1970-01-01
      • 2018-05-29
      • 2016-09-29
      • 1970-01-01
      • 2017-07-02
      • 2020-11-19
      • 2013-08-23
      • 2021-09-07
      相关资源
      最近更新 更多