{"record":{"id":"af36772007b75bb6","repo":"ATH-MaaS/Pixelle-Video","slug":"str-e-af3677","errorCode":null,"errorMessage":"str(e)","messagePattern":"str\\(e\\)","errorType":"http","errorClass":"HTTPException","httpStatus":500,"severity":"error","filePath":"api/routers/tts.py","lineNumber":93,"sourceCode":"        # Legacy voice_id support (deprecated)\n        if request.voice_id and not request.workflow:\n            logger.warning(\"voice_id parameter is deprecated, please use workflow instead\")\n            tts_params[\"voice\"] = request.voice_id\n        \n        # Call TTS service\n        audio_path = await pixelle_video.tts(**tts_params)\n        \n        # Get audio duration\n        duration = get_audio_duration(audio_path)\n        \n        return TTSSynthesizeResponse(\n            audio_path=audio_path,\n            duration=duration\n        )\n        \n    except Exception as e:\n        logger.error(f\"TTS synthesis error: {e}\")\n        raise HTTPException(status_code=500, detail=str(e))\n\n","sourceCodeStart":75,"sourceCodeEnd":95,"githubUrl":"https://github.com/ATH-MaaS/Pixelle-Video/blob/848b054e4fae40dabc62ec58e960b573e83793ac/api/routers/tts.py#L75-L95","documentation":"A 500 HTTPException raised in tts_synthesize (api/routers/tts.py:93) by its blanket `except Exception` handler. Any failure during text-to-speech synthesis — engine errors, file writes, invalid input reaching the engine — is caught, logged as 'TTS synthesis error', and re-raised with detail=str(e), so the client sees the raw internal exception text with status 500.","triggerScenarios":"TTS engine/model not installed or fails to load; empty/oversized/unsupported-language text passed to the synthesizer; disk full or unwritable output directory when saving audio_path; downstream synthesis call raising (codec/timeout/license error).","commonSituations":"Server deployed without the TTS model files or missing system dependencies (e.g. espeak for some engines); text containing characters the engine can't handle; audio output directory permissions wrong after a container change; long text exceeding engine limits causing a timeout; str(e) empty for exceptions that carry no message.","solutions":["Read the 'TTS synthesis error: ...' server log to identify the underlying exception.","Verify the TTS engine/model is installed and loadable on the server (run a minimal synthesis in a shell/repl).","Validate the request text client-side: non-empty, within length limits, characters the engine supports, supported language.","Check that the audio output directory exists and is writable by the server process, and that disk space is sufficient.","Replace detail=str(e) with a generic client message and log the traceback server-side; return 400 instead of 500 for invalid input."],"exampleFix":"# before\nexcept Exception as e:\n    logger.error(f\"TTS synthesis error: {e}\")\n    raise HTTPException(status_code=500, detail=str(e))\n# after\nexcept ValueError as e:  # bad input\n    raise HTTPException(status_code=400, detail=f\"Invalid TTS input: {e}\")\nexcept Exception:\n    logger.exception(\"TTS synthesis error\")\n    raise HTTPException(status_code=500, detail=\"TTS synthesis failed\")","handlingStrategy":"validation","validationCode":"# caller-side pre-check before calling the TTS API\ntext = request.text.strip()\nif not text:\n    raise ValueError(\"text is empty\")\nif len(text) > MAX_TTS_LENGTH:\n    raise ValueError(f\"text too long: {len(text)} > {MAX_TTS_LENGTH}\")\nif not is_supported_language(request.language):\n    raise ValueError(f\"unsupported language: {request.language}\")","typeGuard":"def is_valid_tts_request(req) -> bool:\n    return (\n        isinstance(getattr(req, 'text', None), str)\n        and 0 < len(req.text.strip()) <= MAX_TTS_LENGTH\n    )","tryCatchPattern":"try {\n  const res = await fetch('/tts/synthesize', { method: 'POST', body: payload });\n  if (res.status === 500) {\n    // engine/output failure server-side; check server logs for 'TTS synthesis error'\n    return fallbackToAlternateVoiceEngine(payload);\n  }\n  if (res.status === 400) showUserInputError(await res.json());\n  return await res.blob();\n} catch (err) {\n  handleSynthesisFailure(err);\n}","preventionTips":["Validate text length, emptiness, language, and charset before calling the endpoint.","Ensure the TTS engine/model and its system dependencies are installed in the deployment image; smoke-test synthesis at startup.","Confirm the audio output directory exists, is writable, and has free disk space.","Separate 400 (bad input) from 500 (engine failure) server-side; don't return raw str(e) to clients.","Keep a fallback voice engine or cached-audio path for critical flows."],"tags":["http-500","tts","unhandled-exception","audio","fastapi"],"backgroundTag":"internal-server-error-500","analyzedSha":"848b054e4fae40dabc62ec58e960b573e83793ac","analyzedAt":"2026-08-30T03:24:41.468Z","schemaVersion":2},"datasetVersion":"2026-08-30T08:17:16.595Z"}