diff --git a/python/sglang/srt/entrypoints/http_server.py b/python/sglang/srt/entrypoints/http_server.py index d9d649776..d7368383d 100644 --- a/python/sglang/srt/entrypoints/http_server.py +++ b/python/sglang/srt/entrypoints/http_server.py @@ -726,7 +726,21 @@ async def generate_request(obj: GenerateReqInput, request: Request): ): yield b"data: " + dumps_json(out) + b"\n\n" except ValueError as e: - out = {"error": {"message": str(e)}} + # A client disconnect also surfaces here. It's a client-side + # cancellation, not a server error or bad input -- log it and + # stop (the request was already aborted upstream) instead of + # emitting a 400. + if request is not None and await request.is_disconnected(): + logger.info(f"[http_server] Client disconnected: {e}") + return + out = { + "error": { + "message": str(e), + "type": "invalid_request_error", + "code": 400, + "retryable": False, + } + } logger.error(f"[http_server] Error: {e}") yield b"data: " + dumps_json(out) + b"\n\n" yield b"data: [DONE]\n\n" diff --git a/python/sglang/srt/multimodal/processors/base_processor.py b/python/sglang/srt/multimodal/processors/base_processor.py index 964583a0e..761ba4dae 100644 --- a/python/sglang/srt/multimodal/processors/base_processor.py +++ b/python/sglang/srt/multimodal/processors/base_processor.py @@ -549,8 +549,17 @@ class BaseMultimodalProcessor(ABC): elif modality == Modality.AUDIO: return load_audio(data, audio_sample_rate) + except ValueError as e: + # Bad input (e.g. invalid base64) -> 400, not 500. + data_str = str(data) + if len(data_str) > 100: + data_str = data_str[:100] + "..." + raise ValueError(f"Error while loading data {data_str}: {e}") from e except Exception as e: - raise RuntimeError(f"Error while loading data {data}: {e}") + data_str = str(data) + if len(data_str) > 100: + data_str = data_str[:100] + "..." + raise RuntimeError(f"Error while loading data {data_str}: {e}") from e @staticmethod def _get_preprocessed_input_format(data):