Как выкинуть ошибки изнутри безсерверной лямбды - PullRequest
0 голосов
/ 09 мая 2018

Может кто-нибудь помочь мне понять, как генерировать ошибки аутентификации в лямбда-приложении graphQL? Я использую GraphQL-йогу с безсерверным сервером, и я могу аутентифицировать запрос и либо вернуть пользователя, которого я получил от jwt, {} без токена, либо выдать ошибку аутентификации, если токен старый. Когда я выбрасываю ошибку, она попадает в оператор catch моего блока authenticate, но я понятия не имею, как на самом деле вернуть его из лямбды.

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

Ответы [ 2 ]

0 голосов
/ 15 мая 2018

Я наконец получил это! Вот правильный способ выбросить, перехватить и отформатировать ошибки, которые генерируются в лямбда-функции без сервера. Хитрость заключается в создании модифицированного обратного вызова, который передается в обработчик graphQL. Когда функция будет решена, она будет проходить через любой код, который вы захотите.

Кроме того, Seanvm был прав, что важно определить тип лямбда-функции - безсерверный по умолчанию настраивает прокси-лямбда-функцию, что требует форматирования вывода, как я это делаю ниже, и передачи значения 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);
};
0 голосов
/ 10 мая 2018

Один из вариантов настройки вашего сообщения об ошибке - создать новый экземпляр класса 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

...