1use super::*;
2use coil_template::TemplateModelError;
3use std::path::PathBuf;
4
5#[derive(Debug, Error)]
6pub enum RuntimeBuildError {
7 #[error(transparent)]
8 Config(#[from] ConfigError),
9 #[error(transparent)]
10 Registration(#[from] RegistrationError),
11 #[error(transparent)]
12 Capability(#[from] CapabilityValidationError),
13 #[error(transparent)]
14 ModuleInstallation(#[from] ModuleInstallationError),
15 #[error(transparent)]
16 Data(#[from] DataModelError),
17 #[error(transparent)]
18 Route(#[from] RouteBuildError),
19 #[error(transparent)]
20 Observability(#[from] ObservabilityError),
21 #[error(transparent)]
22 Wasm(#[from] WasmModelError),
23 #[error(transparent)]
24 Jobs(#[from] JobsModelError),
25 #[error(transparent)]
26 Ops(#[from] OpsModelError),
27 #[error(transparent)]
28 Template(#[from] TemplateModelError),
29 #[error("failed to read template source `{path}`: {message}")]
30 TemplateSourceRead { path: String, message: String },
31 #[error("failed to parse template source `{path}`: {message}")]
32 TemplateSourceParse { path: String, message: String },
33 #[error("failed to read storefront catalog `{path}`: {message}")]
34 StorefrontCatalogRead { path: String, message: String },
35 #[error("failed to parse storefront catalog `{path}`: {message}")]
36 StorefrontCatalogParse { path: String, message: String },
37 #[error("storefront catalog `{path}` is invalid: {message}")]
38 StorefrontCatalogValidation { path: String, message: String },
39 #[error("template source `{path}` uses unsupported directive `{directive}`")]
40 TemplateSourceUnsupportedDirective { path: String, directive: String },
41 #[error("customer app root `{path}` does not exist")]
42 MissingCustomerAppRoot { path: String },
43 #[error("customer app root `{path}` is not a directory")]
44 CustomerAppRootNotDirectory { path: String },
45 #[error("customer app templates directory `{path}` does not exist")]
46 MissingTemplateTree { path: String },
47 #[error("customer app templates directory `{path}` does not contain any `.html` templates")]
48 EmptyTemplateTree { path: String },
49 #[error("configured auth package `{configured}` does not match loaded package `{actual}`")]
50 AuthPackageMismatch { configured: String, actual: String },
51 #[error("linked customer plugin `{plugin_id}` is registered more than once")]
52 DuplicateCustomerPlugin { plugin_id: String },
53 #[error("failed to register linked customer plugin `{plugin_id}`: {message}")]
54 CustomerPluginRegistration { plugin_id: String, message: String },
55 #[error(
56 "installed extension `{extension_id}` targets customer app `{actual}` but runtime config is `{configured}`"
57 )]
58 ExtensionCustomerAppMismatch {
59 extension_id: String,
60 configured: String,
61 actual: String,
62 },
63 #[error("handler `{route}` is registered more than once")]
64 DuplicateHandler { route: String },
65 #[error("handler `{route}` does not match a registered route")]
66 UnknownHandlerRoute { route: String },
67 #[error(
68 "extension slot `{surface}` for `{kind:?}` is declared by both `{first_module}` and `{second_module}`"
69 )]
70 DuplicateExtensionSlot {
71 kind: ExtensionPointKind,
72 surface: String,
73 first_module: String,
74 second_module: String,
75 },
76 #[error(
77 "installed extension `{extension_id}` handler `{handler_id}` targets `{point}` surface `{surface}` without a declared slot"
78 )]
79 UnknownExtensionSlot {
80 extension_id: String,
81 handler_id: String,
82 point: ExtensionPointKind,
83 surface: String,
84 },
85 #[error(
86 "job `{job}` is declared by both `{first_module}` and `{second_module}`; runtime job names must be unique"
87 )]
88 DuplicateRuntimeJobName {
89 job: String,
90 first_module: String,
91 second_module: String,
92 },
93 #[error(
94 "runtime data repository `{repository}` is declared by both `{first_module}` and `{second_module}`"
95 )]
96 DuplicateDataRepository {
97 repository: String,
98 first_module: String,
99 second_module: String,
100 },
101 #[error("event subscription `{event}` in module `{module}` must target a declared job")]
102 EventSubscriptionMissingJob { module: String, event: String },
103 #[error("event subscription `{event}` in module `{module}` targets unknown job `{job}`")]
104 UnknownEventSubscriptionJob {
105 module: String,
106 event: String,
107 job: String,
108 },
109 #[error(
110 "event subscription `{event}` in module `{module}` targets job `{job}` with trigger `{trigger:?}`; domain-event subscriptions must target domain-event jobs"
111 )]
112 EventSubscriptionTriggerMismatch {
113 module: String,
114 event: String,
115 job: String,
116 trigger: JobTriggerKind,
117 },
118 #[error(
119 "customer app manifest enables modules not linked into the customer binary: {modules:?}"
120 )]
121 CustomerManifestMissingLinkedModules { modules: Vec<String> },
122 #[error("customer app manifest `{path}` could not be loaded: {reason}")]
123 CustomerManifestLoad { path: PathBuf, reason: String },
124 #[error("customer-root runtime builder requires `with_customer_root(...)` before build or run")]
125 CustomerRootNotConfigured,
126}
127
128#[derive(Debug, Error)]
129pub enum RuntimeBootstrapError {
130 #[error(transparent)]
131 Build(#[from] RuntimeBuildError),
132 #[error(transparent)]
133 Server(#[from] RuntimeServerError),
134 #[error("failed to resolve the current working directory: {0}")]
135 CurrentDirectory(std::io::Error),
136 #[error(
137 "could not discover a platform config under `{app_root}`; set `COIL_CONFIG` or add `platform.toml` / `platform.dev.toml`"
138 )]
139 ConfigNotFound { app_root: PathBuf },
140 #[error("platform config `{path}` could not be loaded: {reason}")]
141 ConfigLoad { path: PathBuf, reason: String },
142 #[error("customer app manifest `{path}` could not be loaded: {reason}")]
143 ManifestLoad { path: PathBuf, reason: String },
144 #[error("auth package `{package}` could not be loaded from `{app_root}`: {reason}")]
145 AuthPackageLoad {
146 package: String,
147 app_root: PathBuf,
148 reason: String,
149 },
150 #[error("required environment variable `{name}` is missing or empty")]
151 MissingEnvironmentVariable { name: &'static str },
152 #[error("failed to bind the customer server to `{bind}`: {reason}")]
153 Bind { bind: String, reason: String },
154 #[error("customer server exited with an error: {reason}")]
155 Serve { reason: String },
156}