【问题标题】:Custom exception name instead of UserLambdaValidationException自定义异常名称而不是 UserLambdaValidationException
【发布时间】:2018-05-08 05:25:24
【问题描述】:

我使用 Cognito 的 Pre sign-up 触发器来验证用户注册。如果某些验证失败,则函数会响应自定义错误。客户端只接收UserLambdaValidationException 作为ErrorCode。

有没有办法接收自定义错误名称?

当前使用示例:

exports.handler = function(event, context, callback) {                
  function AccountAlreadyExistsError(message) {
    this.name = "AccountAlreadyExistsError";
    this.message = message;
  }
  AccountAlreadyExistsError.prototype = new Error();

  const error = new AccountAlreadyExistsError("Account is in use!");
  callback(error);
};

我想在我们的客户端中获得AccountAlreadyExistsError,而不是UserLambdaValidationException。

【问题讨论】:

  • 您在这里找到解决方案了吗?

标签: node.js amazon-web-services amazon-cognito


【解决方案1】:

只有当它是 Lambda 代理时,您才能自定义异常标头,使用 API Gateway(x-amzn-errortype 标头),在任何其他情况下,您需要解析异常消息以获取您的自定义异常,这里是一个示例我如何管理 Cognito lambda 触发器的异常,只是向您展示这个想法:

/*
  Lambda Code, could be in a Lambda layer
*/
const EXCEPTION_TYPE_DELIMITER = "etype"
const EXCEPTION_MESSAGE_DELIMITER = "emsg";

const beTagged = (tag, txt) => {
  return "<" + tag + ">" + txt + "</" + tag + ">";
};

class UserNotAllowedException extends Error {
   constructor (message) {
     super(beTagged(EXCEPTION_MESSAGE_DELIMITER, message))
     Error.captureStackTrace(this, this.constructor);
     this.name = beTagged(EXCEPTION_TYPE_DELIMITER, this.constructor.name);
   }
}

exports.handler = async (event, context, callback) => {
    // Your logic, etc..  
    throw new UserNotAllowedException("You are blocked :(");
}

这是解析器

/*
  Client Code
*/
const EXCEPTION_TYPE_DELIMITER_REGEX = /<etype>(.*?)<\/etype>/g;
const EXCEPTION_TYPE_UNTAG_REGEX = /<\/?etype>/g;
const EXCEPTION_MESSAGE_DELIMITER_REGEX = /<emsg>(.*?)<\/emsg>/g;
const EXCEPTION_MESSAGE_UNTAG_REGEX = /<\/?emsg>/g;

const untag = (txt, delimiterRegex, untagRegex) => {
  return txt.match(delimiterRegex).map(etype => {
    return etype.replace(untagRegex,"");
  })[0];
};

const resolveException = (exceptionMessage) => {
    const exceptionType = untag(exceptionMessage, EXCEPTION_TYPE_DELIMITER_REGEX, EXCEPTION_TYPE_UNTAG_REGEX);
    const exceptionMessage = untag(exceptionMessage, EXCEPTION_MESSAGE_DELIMITER_REGEX, EXCEPTION_MESSAGE_UNTAG_REGEX);
    // Your logic to determine what exception is the exceptionType
    return new YourResolvedException(exceptionMessage);
};

try {
   // This guy should throw the exception
   return await Auth.signUp(params);
} catch (e) {
  // Expected message from Cognito Lambda Trigger
  // PreSignUp failed with error <etype>UserNotAllowedException</etype>: <emsg>You are blocked :(</emsg>.
  // For example, here your custom exception resolver
  throw resolveException(e.message);
}

这可以通过一千种方式完成,但对我们来说最好的事情是如果 AWS 服务能够完全自定义异常而没有太多麻烦。

问候!

【讨论】:

    【解决方案2】:

    我最终尝试了它,并且能够在客户端中获得错误消息。使用 AWS CLI、Nodejs 和内置的 Cognito UI 对其进行了测试。我使用以下方法返回了错误:

    var error = new Error('something went wrong..!');
    callback(error,event);
    

    我的所有客户都收到了错误UserLambdaValidationException: PreSignUp failed with error something went wrong..!。甚至callback(error) 也有效。

    【讨论】:

    • 我什至建议,如果你想发送一些有效负载(例如与验证相关的),你可以 JSON.stringify 你的错误对象及其有效负载并发送callback(new Error(stringifiedError), event) 以访问您的数据
    • 重载消息以包含数据是非常脆弱的,但可惜它似乎是目前唯一的方法。
    猜你喜欢
    • 1970-01-01
    • 2016-04-29
    • 1970-01-01
    • 1970-01-01
    • 2023-03-21
    • 1970-01-01
    • 2019-03-21
    • 2012-07-20
    • 1970-01-01
    相关资源
    最近更新 更多