在使用NestJS上传GraphQL时超过了最大调用堆栈大小



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

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 exceededn    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;
}
}

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

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

请参阅这条注释,它概述了这里引用的方法。

对于将来的读者,这里是如何一劳永逸地解决这个问题。

问题是@nestjs/graphql的依赖,apollo-server-core,依赖于旧版本的graphql-upload (v8.0),这与新版本的Node.js和各种包有冲突。阿波罗服务器v2.21.0似乎已经修复了这个问题,但@nestjs/graphql仍然在v2.16.1上。此外,Apollo Server v3将删除内置的graphql-upload。

在这个评论中建议的解决方案是禁用阿波罗服务器的内置处理上传和使用自己的。这可以通过3个简单的步骤完成:

1。package.json

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

2。src/app.module.ts

禁用Apollo Server的内置上传处理,并在应用程序中添加graphqluploadeexpress中间件。

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/博客/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 */)
}

相关内容

最新更新