synor/crates/synor-hosting/src/error.rs
Gulshan Yadav a70b2c765c feat(hosting): add Synor Hosting subdomain-based web hosting
Add synor-hosting crate for decentralized web hosting with:

- Name Registry: On-chain name→CID mapping with ownership, expiry,
  and custom domain linking
- Domain Verification: CNAME/TXT DNS verification for custom domains
- Hosting Router: Host-based routing with SPA support, redirects,
  and custom headers
- synor.json: Project configuration for build, routes, and error pages

Users can deploy to myapp.synor.cc and optionally link custom domains.

23 tests passing.
2026-01-10 12:34:07 +05:30

129 lines
3.2 KiB
Rust

//! Hosting Error Types
//!
//! Error definitions for the Synor Hosting system.
use thiserror::Error;
/// Hosting errors
#[derive(Debug, Error)]
pub enum Error {
/// Invalid name format
#[error("invalid name: {0}")]
InvalidName(String),
/// Name is reserved
#[error("name '{0}' is reserved")]
ReservedName(String),
/// Name is too similar to a reserved name (confusable)
#[error("name '{0}' is too similar to reserved name '{1}'")]
ConfusableName(String, String),
/// Name not found in registry
#[error("name '{0}' not found")]
NameNotFound(String),
/// Name already registered
#[error("name '{0}' is already registered")]
NameAlreadyRegistered(String),
/// Name is already taken
#[error("name '{0}' is already taken")]
NameTaken(String),
/// Invalid operation
#[error("invalid operation: {0}")]
InvalidOperation(String),
/// Name has expired
#[error("name '{0}' has expired")]
NameExpired(String),
/// Not the owner of this name
#[error("not the owner of this name")]
NotOwner,
/// Domain already linked to another name
#[error("domain '{0}' is already linked to another name")]
DomainAlreadyLinked(String),
/// Domain not verified
#[error("domain '{0}' is not verified")]
DomainNotVerified(String),
/// Domain verification pending
#[error("domain '{0}' verification is pending")]
DomainVerificationPending(String),
/// Domain verification expired
#[error("domain '{0}' verification has expired")]
DomainVerificationExpired(String),
/// Domain not found
#[error("domain '{0}' not found")]
DomainNotFound(String),
/// Domain verification failed
#[error("verification failed for domain '{0}': {1}")]
VerificationFailed(String, String),
/// Invalid domain format
#[error("invalid domain: {0}")]
InvalidDomain(String),
/// Unknown host
#[error("unknown host: {0}")]
UnknownHost(String),
/// Redirect response
#[error("redirect to {to} with status {status}")]
Redirect {
/// Target URL
to: String,
/// HTTP status code
status: u16,
},
/// Configuration error
#[error("configuration error: {0}")]
Config(String),
/// Storage error
#[error("storage error: {0}")]
Storage(String),
/// DNS resolution error
#[error("DNS error: {0}")]
Dns(String),
/// IO error
#[error("IO error: {0}")]
Io(#[from] std::io::Error),
/// JSON parsing error
#[error("JSON error: {0}")]
Json(#[from] serde_json::Error),
}
/// Result type alias
pub type Result<T> = std::result::Result<T, Error>;
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_error_display() {
let err = Error::InvalidName("bad-name!".to_string());
assert_eq!(err.to_string(), "invalid name: bad-name!");
let err = Error::NameNotFound("myapp".to_string());
assert_eq!(err.to_string(), "name 'myapp' not found");
let err = Error::Redirect {
to: "https://example.com".to_string(),
status: 301,
};
assert!(err.to_string().contains("redirect"));
}
}