Документация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 и действии.
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 postfrom 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 на соответствие их аннотациям.
from nexy.http import Header async def GET(q: str, limit: int = 10, x_token: str = Header(...)): return {"q": q, "limit": limit}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 одним сообщением в каждом поле. См. Действия.
Пользовательские страницы ошибок
<h1>Page not found</h1><p>The link may be old. <a href="/">Start from the home page</a>.</p><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 возвращается на страницу, при неудаче отображается страница с ошибкой. См. Действия.
Контрольный список, когда страница отвечает не на тот вопрос
- Смотрите на статус, а не на страницу. Пользовательский
notfound.nexyпо-прежнему отвечает на404. - Прочтите терминал. Страница, которую не удалось импортировать, не зарегистрирована, поэтому ее URL-адрес отвечает
404, пока файл существует. Ошибка импорта есть в журнале. - Проверьте расширение. При
useCSR = True,.nexyстраницы относятся к режиму сервера; страница в неправильном режиме не является маршрутом. - Проверьте глубину.
notfound.nexyилиerrors.nexyработает только при наличии корневой копии. - Запросите JSON с помощью
Accept: application/json, чтобы увидеть форму, которую получает ваш API-клиент. - Цитируйте ссылку на
500при открытии задачи или поиске в журнале.
Следующие шаги
- Страницы ошибок: полное поведение страницы с примерами.
- Проверка и ошибки: обработчики API
- Устранение неполадок: ошибки, с которыми люди действительно столкнулись
- Тестирование: подтверждение статуса и тела