如何从无服务器 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

如何从无提交按钮调用 Struts2 操作

如何从无服务器应用程序安全地连接到 AWS DynamoDB 或其他 aws 数据库

无服务器框架 Lambda AppSync 错误

AWS API Gateway - Lambda - 内部服务器错误

直接从无窗口 Linux 终端启动 OpenGL 应用程序