Encodera

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.

Оглавление

Обработка ошибок

Ошибки случаются: статья не найдена, у пользователя нет прав, база недоступна. AdonisJS ловит все исключения, которые вылетели из маршрутов и контроллеров, в одном месте — глобальном обработчике. Он решает, что показать посетителю и что записать в журнал.

Обработчик

Файл app/exceptions/handler.ts уже есть в проекте:

// app/exceptions/handler.ts
import app from '@adonisjs/core/services/app'
import { HttpContext, ExceptionHandler } from '@adonisjs/core/http'
import type { StatusPageRange, StatusPageRenderer } from '@adonisjs/core/types/http'
 
export default class HttpExceptionHandler extends ExceptionHandler {
  protected debug = !app.inProduction
  protected renderStatusPages = app.inProduction
 
  protected statusPages: Record<StatusPageRange, StatusPageRenderer> = {
    '404': (error, { view }) => view.render('pages/errors/not_found', { error }),
    '500..599': (error, { view }) => view.render('pages/errors/server_error', { error }),
  }
 
  async handle(error: unknown, ctx: HttpContext) {
    return super.handle(error, ctx)
  }
 
  async report(error: unknown, ctx: HttpContext) {
    return super.report(error, ctx)
  }
}
Свойство или методЧто делает
debugВ разработке показывает подробную страницу с ошибкой и стеком вызовов
renderStatusPagesНа сервере включает красивые страницы ошибок
statusPagesКакой шаблон показать для какого статуса
handleФормирует ответ посетителю
reportЗаписывает ошибку в журнал

Страница 404

{{-- resources/views/pages/errors/not_found.edge --}}
@layout({ title: 'Страница не найдена' })
  <h1>Такой страницы нет</h1>
  <p><a href="{{ route('posts.index') }}">Вернуться к статьям</a></p>
@end

Шаблон показывается для любого ответа 404, например когда Post.findOrFail не нашёл статью. В режиме разработки вместо него вы увидите отладочную страницу; чтобы проверить свою, временно поставьте renderStatusPages = true.

Своё исключение

node ace make:exception PostLocked
// app/exceptions/post_locked_exception.ts
import { Exception } from '@adonisjs/core/exceptions'
 
export default class PostLockedException extends Exception {
  static status = 423
  static code = 'E_POST_LOCKED'
  static message = 'Статья закрыта для комментариев'
}
// app/controllers/comments_controller.ts
import PostLockedException from '#exceptions/post_locked_exception'
 
if (post.isLocked) {
  throw new PostLockedException()
}

Обработчик вернёт статус 423 и текст сообщения: для JSON-клиента — в JSON, для браузера — страницей.

Свой ответ для исключения

Исключение может само решить, как отвечать, — для этого в нём объявляют метод handle:

// app/exceptions/post_locked_exception.ts
async handle(error: this, ctx: HttpContext) {
  ctx.session.flash('error', error.message)
  return ctx.response.redirect().back()
}

Тогда посетитель вернётся на страницу статьи и увидит flash-сообщение. HttpContext импортируйте из @adonisjs/core/http.

Частая ошибка

На сервере забывают выставить NODE_ENV=production. Тогда app.inProduction ложно, debug включён, и при любой ошибке посетитель видит стек вызовов, пути к файлам и куски кода. Проверяйте NODE_ENV в .env рабочего сервера.

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.