Files
vllm-omni/vllm_omni/entrypoints/serve/utils/errors.py
T

92 lines
3.2 KiB
Python
Raw Normal View History

# SPDX-License-Identifier: Apache-2.0
# SPDX-FileCopyrightText: Copyright contributors to the vLLM-Omni project
"""Server-level error helpers for vLLM-Omni entrypoints.
Use this module for FastAPI/app exception handling and engine-failure response
construction that is not owned by a single OpenAI endpoint family."""
from typing import Any
from fastapi import Request
from fastapi.responses import JSONResponse
from vllm.entrypoints.launchers.launcher import terminate_if_errored
from vllm.entrypoints.serve import create_error_response
from vllm.logger import init_logger
from vllm.v1.engine.exceptions import EngineDeadError, EngineGenerateError
logger = init_logger(__name__)
def _get_request_id_from_request(req: Request) -> str | None:
return req.state.request_metadata.request_id if hasattr(req.state, "request_metadata") else None
def _build_engine_error_payload(
exc: EngineDeadError | EngineGenerateError,
*,
request_id: str | None,
) -> tuple[dict[str, Any], int]:
err = create_error_response(exc)
payload = err.model_dump()
error_body = payload.get("error", {})
error_body["request_id"] = request_id
error_body["error_stage_id"] = getattr(exc, "error_stage_id", None)
return payload, err.error.code
def _create_engine_error_json_response(
req: Request,
exc: EngineDeadError | EngineGenerateError,
) -> JSONResponse:
request_id = _get_request_id_from_request(req)
error_stage_id = getattr(exc, "error_stage_id", None)
engine = req.app.state.engine_client
if isinstance(exc, EngineDeadError):
# Log Omni-specific diagnostic information for dead engines.
orchestrator_alive = engine.engine.is_alive() if hasattr(engine, "engine") else "N/A"
logger.error(
"EngineDeadError: orchestrator_alive=%s, errored=%s, request_id=%s, error_stage_id=%s",
orchestrator_alive,
engine.errored,
request_id,
error_stage_id,
)
terminate_if_errored(
server=req.app.state.server,
engine=engine,
)
payload, status_code = _build_engine_error_payload(exc, request_id=request_id)
return JSONResponse(content=payload, status_code=status_code)
def _register_omni_exception_handlers(app) -> None:
"""Override upstream vLLM exception handlers with Omni-aware versions.
The upstream ``engine_error_handler`` is designed for ``AsyncLLM`` (single
EngineCore process). Omni uses a multi-stage orchestrator with different
health semantics, so we register our own handlers that:
- Log multi-stage diagnostic info (orchestrator liveness, per-stage health)
when an ``EngineDeadError`` is caught.
- Call ``terminate_if_errored``
- Return an OpenAI-compatible error JSON response.
"""
async def omni_engine_error_handler(
req: Request,
exc: EngineDeadError | EngineGenerateError,
):
request_id = _get_request_id_from_request(req)
if req.app.state.args.log_error_stack:
logger.exception("Engine Exception caught. Request id: %s", request_id)
return _create_engine_error_json_response(req, exc)
app.exception_handler(EngineGenerateError)(omni_engine_error_handler)
app.exception_handler(EngineDeadError)(omni_engine_error_handler)