harry0703/MoneyPrinterTurbo · error · SoniloError

failed to request Sonilo music: {exc}

Error message

failed to request Sonilo music: {exc}

What it means

Raised when any requests.RequestException occurs across the whole video-to-music call: connection setup, headers, body upload, and streaming via iter_lines (the except deliberately wraps the entire with-block so mid-stream drops are caught too). The original requests exception text is embedded. This is the generic transport-failure bucket: DNS, TLS, refused connections, read timeouts, resets.

Source

Thrown at app/services/sonilo.py:306

                response = requests.post(
                    f"{_base_url()}{VIDEO_TO_MUSIC_PATH}",
                    headers={"Authorization": f"Bearer {get_api_key()}"},
                    files={"video": (Path(video_path).name, video_file, "video/mp4")},
                    data={"prompt": prompt} if prompt else None,
                    stream=True,
                    timeout=_request_timeout(),
                )
                with response:
                    if not response.ok:
                        raise SoniloError(
                            f"Sonilo generation failed ({response.status_code}): "
                            f"{_safe_response_error(response)}"
                        )
                    total_bytes, title = _stream_audio(response, temp_audio_path)
        except requests.RequestException as exc:
            # iter_lines() 期间的网络中断同样属于 requests 异常,不能只捕获
            # 建立连接阶段,否则半条音频可能让任务直接异常退出而无法降级。
            raise SoniloError(f"failed to request Sonilo music: {exc}") from exc

        try:
            bgm_service.validate_audio_file(temp_audio_path, timeout_seconds=120)
        except (bgm_service.BgmUploadError, bgm_service.BgmServiceError) as exc:
            raise SoniloError("Sonilo returned audio that FFmpeg cannot decode") from exc
        os.replace(temp_audio_path, output_path)
        temp_audio_path = ""
        logger.info(
            f"Sonilo background music generated: output={output_path}, "
            f"size={total_bytes} bytes, title={title or '-'}"
        )
        return output_path
    finally:
        _remove_file(temp_audio_path)


def generate_bgm(
    video_path: str,

View on GitHub (pinned to 1f9f19c202)

Solutions

  1. Read the embedded exception: name-resolution failure means fix sonilo_base_url or DNS; read timeout means raise the sonilo_timeout config (capped at 1800); SSL errors mean fix cert trust or bypass the MITM proxy; connection refused means a firewall or egress rule.
  2. Verify basic reachability from the app host with a curl HEAD request to the services endpoint.
  3. For long generations, set the sonilo_timeout config near the 1800-second ceiling.
  4. Wrap the task-level call in a bounded retry (1-2 attempts with backoff) since transport errors are usually transient.

Example fix

# before (single attempt)
result = sonilo._request_bgm(video, out, prompt)
# after (bounded retry for transport errors)
for attempt in range(3):
    try:
        result = sonilo._request_bgm(video, out, prompt)
        break
    except sonilo.SoniloError as exc:
        if attempt == 2 or "failed to request Sonilo music" not in str(exc):
            raise
        time.sleep(2 ** attempt)
Defensive patterns

Strategy: retry

Validate before calling

import requests, sonilo

# cheap reachability check before the long job
try:
    requests.get(
        f"{sonilo._base_url()}{sonilo.SERVICES_PATH}",
        headers={"Authorization": f"Bearer {sonilo.get_api_key()}"},
        timeout=10,
    )
except requests.RequestException as exc:
    logger.warning(f"Sonilo unreachable before task: {exc}")

Try / catch

for attempt in range(3):
    try:
        output = sonilo._request_bgm(video, out, prompt)
        break
    except sonilo.SoniloError as exc:
        if "failed to request Sonilo music" not in str(exc) or attempt == 2:
            raise
        time.sleep(2 ** attempt)  # transport errors are transient; DNS/cert faults exhaust fast

Prevention

When it happens

Trigger: DNS failure resolving the sonilo_base_url host; TLS certificate error behind a corporate MITM proxy; connection reset mid-upload of the video proxy; read timeout because generation stalls longer than the configured read timeout (capped at 1800 seconds); proxy or firewall blocking outbound HTTPS.

Common situations: A wrong sonilo_base_url configured (typo, internal URL unreachable from the server); egress firewalls on production hosts; flaky networks during long streams; self-signed-certificate proxies; read timeout configured too low for six-minute generations.

Related errors


AI-assisted analysis of harry0703/MoneyPrinterTurbo@1f9f19c202 (2026-08-14). Data as JSON: /api/errors/4672f7f991d04875. Report an issue: GitHub.