如何从无服务器 lambda 内部抛出错误
Posted
技术标签:
【中文标题】如何从无服务器 lambda 内部抛出错误【英文标题】:How to throw errors from inside a serverless lambda 【发布时间】:2018-10-19 14:26:21 【问题描述】:有人可以帮助我了解如何在 graphQL lambda 应用程序中引发身份验证错误吗?我将graphQL-yoga与无服务器一起使用,我可以对请求进行身份验证,然后返回我从jwt获得的用户, 没有令牌,或者如果令牌旧,则抛出身份验证错误。当我抛出一个错误时,它会被我的身份验证块的 catch 语句捕获,但我不知道如何从 lambda 中实际返回它。
const lambda = new GraphQLServerLambda(
typeDefs,
context: ( event, context ) =>
authenticate(event.headers.Authorization)
.then(user => ( db: mainDb, user))
.catch(e =>
console.log('Caught the auth error here');
throw e;
),
Query: \\ some queries here.... ,
Mutation: \\ some mutations here...
);
如何格式化错误或从正确的位置抛出错误,以便得到实际的格式化错误?相反,我在客户端收到 Unexpected token I in JSON...
错误。显然,我需要在我的 throw
期间进行某种格式设置,但对我来说如何做到这一点并不完全清楚。
如果有帮助,请在我的导出部分。我正在尝试从 try/catch 到 then/catch 的所有方法,此时我似乎已经错过了捕获错误。有没有更好的方法来做到这一点?我需要的主要内容是能够进行身份验证、拒绝错误令牌,否则只为未登录的用户返回 。我很难找到允许未登录用户的自定义授权者,所以这就是我直接在我的 graphQL 端点中进行身份验证的原因
exports.server = (event, context, callback) =>
try
return lambda
.graphqlHandler(event, context, callback)
.then(b => b)
.catch(e => console.log(`can't catch it here $e`));
catch (e)
console.log('or here');
callback(e);
;
【问题讨论】:
【参考方案1】:自定义错误消息的一个选项是创建Error
类的新实例。
一个例子是:
.catch(e =>
console.log('Caught the auth error here');
throw new Error('Authentication Failed');
),
因为回调函数的第一个参数将是错误消息,你也可以直接在处理函数中粘贴一个通用错误:
callback("An error happened!");
您还可以使用 Middy 等中间件来帮助处理错误:
https://github.com/middyjs/middy/blob/master/docs/middlewares.md#httperrorhandler
关于 NodeJS 错误处理的有用链接:
https://www.joyent.com/node-js/production/design/errors
【讨论】:
感谢您的回复。我尝试抛出错误,我可以得到一个 500 错误,但没有别的。我想知道这是否可能是由于 API 网关的配置问题。当我使用 middy 时,即使我抛出错误,我实际上也会得到 200 代码,将其放入 middy 回调(作为字符串、对象或字符串化对象)。 您收到的自定义消息是 500 错误吗?还是一般的内部服务器错误?如果是前者,我相信您可以在消息中使用方括号设置自定义错误代码,如下所示:callback("[418] Your error message");
如果是后者,那么您可能需要仔细检查您是否使用带代理或不带代理的 lambda 集成- ***.com/questions/42474264/…【参考方案2】:
我终于明白了!这是在无服务器的 lambda 函数中引发、捕获和格式化错误的正确方法。诀窍是创建一个修改后的回调,该回调将传递给 graphQL 处理程序。当函数得到解析时,它将运行您想要的任何代码。
此外,Seanvm 是对的,即查看 lambda 函数的类型很重要——无服务器默认设置了一个 proxy-lambda 函数,这需要像我在下面所做的那样格式化输出并将 null 作为错误传递。
exports.server = (event, context, callback) =>
const modifiedCallback = (error, output) =>
if (output.body.includes('401'))
callback(null,
statusCode: 401,
headers: 'Content-Type': 'application/javascript' ,
body: JSON.stringify( message: 'Unauthorized' )
);
else
callback(error, output);
;
return lambda.graphqlHandler(event, context, modifiedCallback);
;
【讨论】:
以上是关于如何从无服务器 lambda 内部抛出错误的主要内容,如果未能解决你的问题,请参考以下文章
aiohttp asyncio.TimeoutError 从无使用 ClientSession
如何从无服务器应用程序安全地连接到 AWS DynamoDB 或其他 aws 数据库