UnhandledPromiseRejectionWarning:错误:在 ApolloServer 调用 `server.applyMiddleware()` 之前必须`await server.s
Posted
技术标签:
【中文标题】UnhandledPromiseRejectionWarning:错误:在 ApolloServer 调用 `server.applyMiddleware()` 之前必须`await server.start()`【英文标题】:UnhandledPromiseRejectionWarning: Error: You must `await server.start()` before calling `server.applyMiddleware()` at ApolloServer 【发布时间】:2021-10-09 07:32:15 【问题描述】:我正在尝试启动我的 nestJs 服务器,但它一直给我这个错误:
UnhandledPromiseRejectionWarning:错误:您必须先await server.start()
,然后再调用server.applyMiddleware()
在 ApolloServer
我什至不知道从哪里调试,因为我还是 NestJs 和 GraphQL 的新手。
【问题讨论】:
在不知道您当前如何运行这些东西的情况下,我们无法为您提供帮助。 【参考方案1】:这是一个已知错误,有一个未解决的问题and a merged PR to fix it。目前,您可以降级到apollo-server-express@^2
【讨论】:
非常感谢。现在工作正常 看起来有计划发布@nestjs/graphql@9
来解决这个问题。根据问题,这个重大突破将在@nestjs/core
和@nestjs/common
重大突破到9 之前很久。但至于何时,我不能说
谢谢@JayMcDoniel 这对我也有用:)【参考方案2】:
完整的工作代码是:
const express = require("express");
const ApolloServer = require("apollo-server-express");
const http = require("http");
const app = express();
const typeDefs = `
type Query
totalPosts: Int!
`;
const resolvers =
Query:
totalPosts: () => 100,
,
;
let apolloServer = null;
async function startServer()
apolloServer = new ApolloServer(
typeDefs,
resolvers,
);
await apolloServer.start();
apolloServer.applyMiddleware( app );
startServer();
const httpserver = http.createServer(app);
app.get("/rest", function (req, res)
res.json( data: "api working" );
);
app.listen(4000, function ()
console.log(`server running on port 4000`);
console.log(`gql path is $apolloServer.graphqlPath`);
);
【讨论】:
这无需更改 libray 版本即可工作,但不需要以下行: const httpserver = http.createServer(app);【参考方案3】:我在升级Ben Awad's Graphql-Next-Typeorm[...] stack 时遇到了这个问题,只需在服务器启动中添加等待即可修复警告
const apolloServer = new ApolloServer(
introspection: true,
schema: await buildSchema(
resolvers: [__dirname + '/resolvers/**/*.js'],
validate: false
),
context: ( req, res ) => (
req,
res,
redis: redisClient
),
formatError
);
// added this line
await apolloServer.start();
apolloServer.applyMiddleware(
app,
cors: false
);
【讨论】:
同样来自 Ben Awad 的课程。cors: false
确实有帮助,但为什么要关闭 introspection
呢?
@BurgerBurglar 我相信你的问题是题外话,内省设置为真,这里有更多关于内省的信息apollographql.com/docs/apollo-server/api/apollo-server/…
我在迁移文档中找不到此信息
@EricBurel 我不确定我理解你的意思或暗示,你能详细说明一下吗?
简单地说,Apollo v3 迁移文档并没有很明确地说明需要等待“开始”,或者至少我找不到相关部分,但你的回答很完美【参考方案4】:
对于 Apollo Server Express 3.0 及更高版本,您需要定义一个接收 typeDefs 和 resolvers 参数的异步函数,然后将服务器分配给与之前相同的 Apollo 初始化,如 here 所示
async function startApolloServer(typeDefs, resolvers)
const server = new ApolloServer(typeDefs, resolvers)
const app = express();
await server.start();
server.applyMiddleware(app, path: '/graphql');
app.listen(PORT, () =>
console.log(`Server is listening on port $PORT$server.graphqlPath`);
)
startApolloServer(typeDefs, resolvers);
【讨论】:
【参考方案5】:您可以将所有内容放在异步函数中并在您的服务器(应用程序,索引...).js 中执行该函数。你也可以查看 npm 包。 https://www.npmjs.com/package/apollo-server-express 例如:
const express = require('express')
, http = require('http')
, path = require('path');
const ApolloServer = require('apollo-server-express');
async function startExpressApolloServer()
const typeDefs = require('./graphql/schemas/schema');
const resolvers = require('./graphql/resolvers/resolver');
const server = new ApolloServer( typeDefs, resolvers );
await server.start();
const app = express();
server.applyMiddleware( app, path: '/api/graphql' );
await new Promise(resolve => app.listen( port: 3001 , resolve));
console.log(`Server ready at http://localhost:3001$server.graphqlPath`);
return server, app ;
startExpressApolloServer();
【讨论】:
+1 基本上来自文档的建议:apollographql.com/docs/apollo-server/api/apollo-server/…【参考方案6】:另一种选择是将您的 apollo 降级到任何 2.x.x。它解决了我的问题
【讨论】:
【参考方案7】:提前启动apollo服务器是不行的。当我必须明确使用 http/https 时会发生什么情况。请看以下案例:
const server = new ApolloServer(
typeDefs: [KeycloakTypeDefs, typeDefs], // 1. Add the Keycloak Type Defs
schemaDirectives: KeycloakSchemaDirectives, // 2. Add the
formatError: new ApolloErrorConverter(),
resolvers: resolvers,
context: ( req ) =>
return makeContextWithDependencies(req);
);
server.applyMiddleware( app );
http.createServer(app).listen(config.server.port, os.hostname());
const options =
key: fs.readFileSync(config.server.ssl.keyFile, "utf8"),
cert: fs.readFileSync(config.server.ssl.certFile, "utf8"),
passphrase: config.server.ssl.passphrase
;
https
.createServer(options, app)
.listen(config.server.securePort, os.hostname());
console.log(
"Server waiting for requests on ports: " +
config.server.port +
"," +
config.server.securePort
);
【讨论】:
如果您有新问题,请点击 按钮提出问题。如果有助于提供上下文,请包含指向此问题的链接。 - From Review【参考方案8】:这里已经有一些很好的答案。但是我们应该知道为什么以及在哪里调用 server.start()。来自阿波罗文档 -
在调用之前总是调用 await server.start() server.applyMiddleware 并启动您的 HTTP 服务器。这允许 你通过崩溃你的来对 Apollo Server 启动失败做出反应 进程而不是开始提供流量。
【讨论】:
【参考方案9】:在 v3 中,如果您使用 apollo-server-express,则需要启动功能https://www.apollographql.com/docs/apollo-server/api/apollo-server/#start。
你可以这样做。
const app = express()
app.use(express.urlencoded( extended: true ))
app.use(express.json())
....
export const startup = async () =>
await server.start()
server.applyMiddleware( app, path: `/api/$configs.region/graphql` )
return app
// call startup in another file to get app
【讨论】:
github.com/nestjs/nest/issues/7543#issuecomment-878811893以上是关于UnhandledPromiseRejectionWarning:错误:在 ApolloServer 调用 `server.applyMiddleware()` 之前必须`await server.s的主要内容,如果未能解决你的问题,请参考以下文章
[Unhandled promise rejection: TypeError: null is not an object (evaluating '_reactNativeImageCropPic