fix(commons): report TTS options allocation failures as out-of-memory
Description
rac_tts_options_from_proto can only fail when it cannot allocate a string, because every caller passes a non-null out. Its three call sites still reported that as RAC_ERROR_DECODING_ERROR ("failed to convert TTSOptions"), so a real out-of-memory condition looked like malformed client input:
rac_tts_synthesize_lifecycle_proto(tts_module.cpp)rac_tts_synthesize_stream_lifecycle_proto(tts_module.cpp)rac_tts_stream_start_proto(rac_tts_stream.cpp)
The adapter now returns a rac_result_t instead of a bool: RAC_ERROR_NULL_POINTER for a null out, RAC_ERROR_OUT_OF_MEMORY when the voice or language copy fails, and RAC_SUCCESS otherwise. The three call sites pass that code through. Only the return type changes. The cleanup and failure-output rules in the header comment stay as they were. Malformed request bytes are still rejected earlier, when the request is parsed, and still return RAC_ERROR_DECODING_ERROR. This matches how rac_vlm_image_from_proto already separates the two cases.
No other code calls the adapter (I checked core/, engines/ and bindings/).
Fixes #1060
Type of Change
- Bug fix
- New feature
- Documentation update
- Refactoring
Testing
- Lint passes locally (
git clang-format --diff HEAD -- corereports no changes to the touched lines) - Added/updated tests for changes
I extended core/tests/test_nonllm_lifecycle_proto_abi.cpp. When rac_commons is a static library, the test defines its own rac_alloc / rac_free / rac_strdup, which keeps the linker from using rac_memory.cpp's versions. The test's rac_strdup returns NULL for one sentinel string. I put that sentinel into TTSOptions.language_code and, separately, into TTSOptions.voice, and checked that all three ABIs return RAC_ERROR_OUT_OF_MEMORY. Malformed request bytes still return RAC_ERROR_DECODING_ERROR on all three. The mock TTS backend gained a trivial synthesize_stream, so the lifecycle stream path gets as far as the options conversion. The interposition only builds when rac_commons is a STATIC_LIBRARY, which is set in core/tests/CMakeLists.txt.
Without the fix, the test reports 6 failures (all of the OOM checks). With it, all checks pass.
cmake --preset macos-debug
cmake --build build/macos-debug
ctest --preset macos-debug # 100% tests passed out of 106
Labels
-
Commons- Changes to shared native code (core)
Checklist
- Code follows project style guidelines
- Self-review completed
- Documentation updated (if needed)
Summary by cubic
Reports out-of-memory conditions during TTS options conversion as RAC_ERROR_OUT_OF_MEMORY instead of RAC_ERROR_DECODING_ERROR, so allocation failures are no longer indistinguishable from malformed client input.
rac_tts_options_from_protonow returnsrac_result_t; its three call sites (lifecycle one-shot, lifecycle stream, and stream sessions) propagate that result instead of always reporting a decoding error.- Malformed request bytes are still rejected during parsing and return
RAC_ERROR_DECODING_ERROR. - Adds ABI tests that inject allocation failures via a test-local
rac_strdupand verify all three call sites reportRAC_ERROR_OUT_OF_MEMORY.
Fixes #1060.
Summary by CodeRabbit
- Bug Fixes
- TTS requests now report more specific errors when options cannot be processed, including insufficient memory and invalid output handling.
- One-shot, streaming, and session-start synthesis consistently preserve and return the underlying option-conversion error instead of reporting a generic decoding failure.
- Malformed TTS requests continue to return a decoding error.