Как я могу вернуть ошибку от контроллера в Loopback 4? - PullRequest
3 голосов
/ 23 марта 2019

У меня есть метод контроллера

// ... inside a controller class

@get('/error', {})
async error() {
  throw new Error("This is the error text");
}

Ответ, который я получаю от этой ошибки:

{ "ошибка": { «statusCode»: 500, "message": "Внутренняя ошибка сервера" } }

Я хотел бы, чтобы ошибка была:

{ "ошибка": { «statusCode»: 500, "message": "Это текст ошибки" } }

Как вернуть ошибку с контроллера в Loopback 4?

Ответы [ 2 ]

3 голосов
/ 25 марта 2019

Привет от команды LoopBack ?

В вашем контроллере или репозитории вы должны выбросить ошибку в точности так, как показано в вашем вопросе.

Теперь, когда LoopBack обнаруживает ошибку, он вызывает действие reject для ее обработки.Встроенная реализация reject регистрирует сообщение через console.error и возвращает HTTP-ответ с кодом ошибки 4xx / 5xx и телом ответа, описывающим ошибку.

По умолчанию LoopBack скрывает фактические сообщения об ошибках вHTTP ответы.Это мера безопасности, предотвращающая утечку на сервер потенциально конфиденциальных данных (пути к файлам, которые не могут быть открыты, IP-адреса серверной службы, которые не могут быть достигнуты).

В этом случае мы используем strong-error-handler для преобразования объектов Error в ответы HTTP.Этот модуль предлагает два режима:

  • Рабочий режим (по умолчанию): ошибки 5xx не содержат никакой дополнительной информации, ошибки 4xx включают частичную информацию.
  • Режим отладки (debug: true): все подробности об ошибках включены в ответ, включая полную трассировку стека.

Режим отладки можно включить, добавив следующую строку в конструктор приложения:

this.bind(RestBindings.ERROR_WRITER_OPTIONS).to({debug: true});

Узнайте больше в наших документах: Последовательность >> Обработка ошибок

В качестве альтернативы, вы можете реализовать свой собственный обработчик ошибок и связать его как последовательность действий reject.См. Настройка последовательности действий в наших документах.

export class MyRejectProvider implements Provider<Reject> {
  constructor(
    @inject(RestBindings.SequenceActions.LOG_ERROR)
    protected logError: LogError,
    @inject(RestBindings.ERROR_WRITER_OPTIONS, {optional: true})
    protected errorWriterOptions?: ErrorWriterOptions,
  ) {}

  value(): Reject {
    return (context, error) => this.action(context, error);
  }

  action({request, response}: HandlerContext, error: Error) {
    const err = <HttpError>error;

    const statusCode = err.statusCode || err.status || 500;
    const body = // convert err to plain data object

    res.statusCode = statusCode;
    res.setHeader('Content-Type', 'application/json; charset=utf-8');
    res.end(JSON.stringify(body), 'utf-8');

    this.logError(error, statusCode, request);
  }
}
0 голосов
/ 25 марта 2019

Для моей ситуации я нашел catch в моем sequence.ts файле.Внутри перехвата он проверил, имеет ли ошибка код состояния 4xx, а если нет, то просто вернул анонимный номер 500.

Вот код, который я искал для выполнения логики:

// sequence.ts
...
} catch (err) {
  console.log(err);
  let code: string = (err.code || 500).toString();
  if (code.length && code[0] === '4') {
    response.status(Number(code) || 500);
    return this.send(response, {
      error: {
        message: err.message,
        name: err.name || 'UnknownError',
        statusCode: code
      }
    });
  }
  return this.reject(context, err);
}
...

Вот как вы говорите, что делать:

// ... inside a controller class

@get('/error', {})
async error() {
  throw {
    code: 400,
    message: "This is the error text",
    name: "IntentionalError"
  }
}
...