ДокументацияPython API и ошибки

Исключения и ошибки

Запрос может завершиться неудачей в четырех местах, и Nexy отвечает на каждый из них по-разному. Эта страница является индексом: найдите статус, который вы видите, затем строку, которая его создала, затем файл, который определяет тело.

Краткая версия

Что случилось Статус Браузер видит Клиент API видит
ни один маршрут не соответствует URL-адресу 404 notfound.nexy, иначе встроенная страница {"detail": "Not Found"}
сегмент пути не соответствует своей аннотации 404 та же страница {"detail": "Not Found"}
поле запроса, заголовка, файла cookie или тела отсутствует или недействительно 422 Тело JSON FastAPI Тело JSON FastAPI
notFound() 404 страница {"detail": ...}
unauthorized() 401 встроенная страница {"detail": ...}
forbidden() 403 встроенная страница {"detail": ...}
raise HTTPException(409, ...) 409 встроенная страница {"detail": ...}
исключение, ничего не поймано 500 errors.nexy, иначе встроенная страница {"detail", "reference"}
redirect(url) 307 пункт назначения, нет страницы пункт назначения, нет тела
permanentRedirect(url) 308 пункт назначения, нет страницы пункт назначения

Клиент API — это запрос, заголовок которого Accept запрашивает JSON, а не страницу:

curl -H "Accept: application/json" http://localhost:3000/api/items/500# {"detail":"Out of range"}

Откуда берется неудача

Один запрос, четыре выхода
Browser ──► Middleware ──► Router ──► Page or handler
                 │            │             │
                 │            │             ├─ return ───────────► 200
                 │            │             ├─ HTTPException ────► its status
                 │            │             └─ other exception ───► 500
                 │            └─ no match ────────────────────────► 404
                 └─ raises ──────────────────────────────────────► 500
Этап Что может выйти из строя Ответ
Промежуточное ПО ваши middleware.py, CORS, сеансы статус исключения, иначе 500
Маршрутизатор URL-адрес не соответствует ни одному файлу 404
Валидация сегмент пути не может быть преобразован 404
Валидация поле запроса, заголовка, файла cookie или тела 422
Страница, обработчик, действие, защита HTTPException его статус
Страница, обработчик, действие, защита что-нибудь еще 500

Уйти откуда угодно

redirect, permanentRedirect, notFound, forbidden и unauthorized вызывают исключение HTTP, поэтому один и тот же вызов работает на странице .nexy, обработчике API, модульном контроллере, защите, dependencies.py и действии.

src/routes/posts/[slug].py
from nexy import notFound, redirect from src.posts import find  async def GET(slug: str):    post = find(slug)    if post is None:        notFound("No such post")    if post.moved_to:        redirect(post.moved_to)    return post
src/apps/posts/posts_by_slug_controller.py
from nexy import notFound, redirectfrom nexy.decorators import Controller from src.posts import find  @Controller("/posts/{slug}")class PostsBySlugController:    async def get(self, slug: str):        post = find(slug)        if post is None:            notFound("No such post")        if post.moved_to:            redirect(post.moved_to)        return post

Перечислите контроллер в controllers корневого модуля.

Позвонить Ответ Когда
notFound(detail=None) 404 ресурс не существует
unauthorized(detail=None, scheme=None) 401 посетитель должен сначала войти в систему
forbidden(detail=None) 403 посетитель известен, но может не видеть этого
redirect(url, status=307) 307 отправьте их в другое место, сохранив метод
redirect(url, status=303) 303 после формы: следующий запрос — GET
permanentRedirect(url) 308 перемещенная страница, которую поисковые системы должны запомнить

Создайте пункт назначения на основе ценностей, которым вы доверяете. redirect(request.query_params["next"]) отправляет посетителей туда, где указано в ссылке; это открытое перенаправление. Пункт назначения, содержащий разрыв строки, отклоняется.

Проверка: 422 или 404.

Параметры обработчика проверяются FastAPI на соответствие их аннотациям.

src/routes/api/search.py
from nexy.http import Header  async def GET(q: str, limit: int = 10, x_token: str = Header(...)):    return {"q": q, "limit": limit}
src/apps/search/search_api_controller.py
from nexy.decorators import Controllerfrom nexy.http import Header  @Controller("/api/search")class SearchApiController:    async def get(self, q: str, limit: int = 10, x_token: str = Header(...)):        return {"q": q, "limit": limit}

Перечислите контроллер в controllers корневого модуля.

Проблема Статус Почему
отсутствующий или неверный запрос, заголовок, поле cookie или тело 422 запрос дошел до обработчика, данные неверны
неверный сегмент пути (/api/users/abc для id: int) 404 в папке нет маршрута для неномера, поэтому URL-адрес не существует

Тело 422 имеет стандартную форму FastAPI, поэтому клиенты и созданные SDK продолжают работать:

{"detail": [{"loc": ["query", "q"], "msg": "Field required", "type": "missing"}]}

Для формы или действия клиент получает ActionError с status и detail; 422 также заполняет error.fields одним сообщением в каждом поле. См. Действия.

Пользовательские страницы ошибок

источник/маршруты/notfound.nexy
<h1>Page not found</h1><p>The link may be old. <a href="/">Start from the home page</a>.</p>
src/маршруты/errors.nexy
<h1>Something went wrong</h1><p>Try again in a moment.</p>
Файл Статус Область применения
src/routes/notfound.nexy 404 каждый маршрут проекта
src/routes/errors.nexy 500 каждый маршрут проекта
src/routes/forbidden.nexy 403 каждый маршрут проекта
src/routes/unauthorized.nexy 401 каждый маршрут проекта
src/routes/blog/notfound.nexy 404 /blog и ниже
src/routes/blog/errors.nexy 500 /blog и ниже
src/routes/loading.nexy - зарезервировано, пока нет эффекта времени выполнения

Один файл где-то в маршрутах устанавливает ответ на свой статус: копия в корне отвечает всему проекту, копия в папке отвечает этой папке, и побеждает самый глубокий файл, соответствующий URL-адресу. URL-адрес за пределами каждой копии и статус без файла вообще получают встроенные страницы со стилем. См. Страниц ошибок в папке.

Модульный маршрутизатор не имеет страницы ошибки в файле: 404, 500, 403 или 401 получают встроенную стилизованную страницу. Страницы ошибок на папку — это соглашение файлового маршрутизатора.

Необработанные исключения

Исключение, когда ничего не обнаружено, записывается один раз со ссылкой на источник и код вокруг него. Статус 500, тело зависит от окружающей среды.

nexy dev nexy build затем nexy start
Браузер ошибка, строки вашего кода и обратная трассировка errors.nexy, иначе встроенная страница со ссылкой
API-клиент {"detail", "reference", "error"} {"detail", "reference"}
Терминал исключение и строки вашего кода исключение, вся трассировка и ссылка
  x ZeroDivisionError: division by zero  GET /boom  ref fe6a5217    at src/routes/boom.py:2 in GET       1 | def GET():       2 |     return {"a": 1 / 0}

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

Действия и формы

Действие — это конечная точка POST со сгенерированным путем. Его неудачи подчиняются тем же правилам:

Ситуация Статус Клиент
поле отсутствует или недействительно 422 ActionError с fields
HTTPException(403) поднят в иске 403 ActionError с status и detail
необработанное исключение 500 ActionError; ссылка есть в журнале сервера
заголовок Origin — это другой сайт 403 отказано до начала действия

Форма без JavaScript сообщений о пути действия; при успехе ответ 303 возвращается на страницу, при неудаче отображается страница с ошибкой. См. Действия.

Контрольный список, когда страница отвечает не на тот вопрос

  1. Смотрите на статус, а не на страницу. Пользовательский notfound.nexy по-прежнему отвечает на 404.
  2. Прочтите терминал. Страница, которую не удалось импортировать, не зарегистрирована, поэтому ее URL-адрес отвечает 404, пока файл существует. Ошибка импорта есть в журнале.
  3. Проверьте расширение. При useCSR = True, .nexy страницы относятся к режиму сервера; страница в неправильном режиме не является маршрутом.
  4. Проверьте глубину. notfound.nexy или errors.nexy работает только при наличии корневой копии.
  5. Запросите JSON с помощью Accept: application/json, чтобы увидеть форму, которую получает ваш API-клиент.
  6. Цитируйте ссылку на 500 при открытии задачи или поиске в журнале.

Следующие шаги

Изменить на GitHub

Enter открывает результат, Esc закрывает.