【问题标题】:Raising Exception from ApiRouter does not run the exception handler, returns 500 internal server error instead. FAST API从 ApiRouter 引发异常不会运行异常处理程序,而是返回 500 内部服务器错误。快速 API
【发布时间】:2021-09-23 20:40:00
【问题描述】:

我正在使用添加到快速 API 的 API 路由器在快速 API 中引发自定义异常。我正在定义异常类和处理程序,并使用以下代码添加它们。它以前可以工作,现在我不太确定是什么问题。添加了中间件,所以这可能是问题所在?

app = FastAPI()

origins = [
    "*",    # Restrict these in the future?
]

app.include_router(memblock_router.router)
app.include_router(event_router.router)

app.add_exception_handler(UnauthorizedException, unauthorized_exception_handler)
app.add_exception_handler(InvalidParameterException, invalid_parameter_exception_handler)
app.add_exception_handler(DatabaseException, database_exception_handler)
app.add_exception_handler(ElasticsearchException, elasticsearch_exception_handler)
app.add_exception_handler(ParsingException, parsing_exception_handler)
app.add_exception_handler(ForbiddenErrorMessage, forbidden_error_message_exception)
app.add_exception_handler(UnsupportedErrorMessage, unsupported_message)
app.add_exception_handler(RequestValidationError, validation_exception_handler)

app.add_middleware(
    CORSMiddleware,
    allow_origins=origins,
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

我正在像这样定义异常和处理程序

class UnauthorizedException(Exception):
    pass

def unauthorized_exception_handler(request: Request, exc: UnauthorizedException):
    print(str(traceback.format_exc()))
    return JSONResponse(status_code=status.HTTP_401_UNAUTHORIZED,
                        content={"error": "unauthorized"},
                        headers=get_response_headers())

【问题讨论】:

  • 添加异常中间件。 app.add_middleware(ExceptionMiddleware, handlers=app.exception_handlers)

标签: python http error-handling fastapi starlette


【解决方案1】:

我遇到了同样的问题,在我的情况下,问题与进口有关。我有一个这样的项目结构:

.
├── Dockerfile
├── app
│   ...
│   ├── main.py
│   ├── repositories
│   │   ├── __init__.py
│   │   └── repository.py
└── requirements.txt

repository.py 包含我要处理的一类错误:

# app/repositories/repository.py

class RepositoryError(Exception):
    pass

main.py我为这个错误注册了一个处理程序:

# app/main.py

...

from repositories.repository import RepositoryError


def get_application() -> FastAPI:
    application = FastAPI(title=PROJECT_NAME, debug=DEBUG, version=VERSION)

    ...

    application.add_exception_handler(RepositoryError, http500_error_handler)

    application.include_router(api_router)

    return application


app = get_application()

if __name__ == '__main__':
    uvicorn.run('app.main:app', host='127.0.0.1', port=8000, reload=True)

如您所见,我使用了相对导入 repositories.repository 而不是 app.repositories.repository。当我深入研究选择适当错误处理程序的代码时,我在starlette/exceptions.py 看到以下内容:

在应用上注册的异常处理程序绑定到 repositories.repository.RepositoryError 类,但捕获的异常属于 app.repositories.repository.RepositoryError 类,这两个类不匹配。当我在main.py 中将导入更改为app.repositories.repository.RepositoryError 时,一切正常。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-02-19
    • 2017-06-29
    • 1970-01-01
    • 2020-06-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多