Skip to main content

suno_core/
error.rs

1//! Error types for the Suno engine.
2
3use std::time::Duration;
4
5/// An error raised by the engine.
6#[derive(Debug, thiserror::Error)]
7pub enum Error {
8    /// The token was rejected, or no session or JWT could be obtained.
9    #[error("authentication failed: {0}")]
10    Auth(String),
11    /// A transport failure talking to Clerk or the Suno API.
12    #[error("could not connect: {0}")]
13    Connection(String),
14    /// The Suno API returned an unexpected status or body.
15    #[error("api error: {0}")]
16    Api(String),
17    /// The Suno API returned `400 Bad Request`.
18    ///
19    /// Distinct from [`Api`](Self::Api) so callers can classify a genuine `400`
20    /// (e.g. "no stems") by status code rather than by body-text matching, which
21    /// would misclassify a `5xx` whose body happens to contain the same text.
22    #[error("bad request: {0}")]
23    BadRequest(String),
24    /// The Suno API returned `404 Not Found` for the requested resource.
25    ///
26    /// Distinct from [`Api`](Self::Api) so a caller can treat a genuine absence
27    /// (a clip with no parent) as `None` without also swallowing a transient
28    /// `5xx`, which must surface as a real error.
29    #[error("not found: {0}")]
30    NotFound(String),
31    /// The Suno API rate-limited the request, with the server's `Retry-After`
32    /// hint in whole seconds when it sent one (it usually does not).
33    #[error("rate limited")]
34    RateLimited { retry_after: Option<Duration> },
35    /// Reading or writing audio metadata tags failed.
36    #[error("tagging failed: {0}")]
37    Tag(String),
38    /// The config file could not be parsed or failed validation.
39    #[error("config error: {0}")]
40    Config(String),
41    /// A request was refused by an engine-side safety guard before it reached
42    /// the network. Used by the crate-wide POST allow-list, which rejects any
43    /// POST to a path outside the small known-safe set so a mutating request
44    /// (above all a credit-spending one) can never be sent by accident.
45    #[error("refused: {0}")]
46    Refused(String),
47}
48
49/// A `Result` whose error is the engine [`Error`].
50pub type Result<T> = std::result::Result<T, Error>;