diff --git a/crates/application/src/cache/mod.rs b/crates/application/src/cache/mod.rs index b32a35ae..e4f3bd5d 100644 --- a/crates/application/src/cache/mod.rs +++ b/crates/application/src/cache/mod.rs @@ -125,10 +125,9 @@ pub struct CacheKey { impl fmt::Debug for CacheKey { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let mut builder = f.debug_struct("CacheKey"); - if let Ok(p) = self.path.as_root_udf_path() { - builder.field("path", p); - } builder + .field("path", &self.path.udf_path) + .field("component", &self.path.component) .field("args", &self.args) .field("identity", &self.identity) .field("journal", &self.journal) diff --git a/crates/application/src/lib.rs b/crates/application/src/lib.rs index 395aa3a1..2226ff1a 100644 --- a/crates/application/src/lib.rs +++ b/crates/application/src/lib.rs @@ -1157,9 +1157,10 @@ impl Application { }) else { let missing_or_internal = format!( - "Could not find function for '{}'. Did you forget to run `npx convex dev` or `npx \ - convex deploy`?", - String::from(canonicalized_path.into_root_udf_path()?.strip()) + "Could not find function for '{}'{}. Did you forget to run `npx convex dev` or \ + `npx convex deploy`?", + String::from(canonicalized_path.udf_path.strip()), + canonicalized_path.component.in_component_str(), ); return Ok(Err(FunctionError { error: RedactedJsError::from_js_error( diff --git a/crates/application/src/tests/cron_jobs.rs b/crates/application/src/tests/cron_jobs.rs index 33c5bac5..c6ab1a33 100644 --- a/crates/application/src/tests/cron_jobs.rs +++ b/crates/application/src/tests/cron_jobs.rs @@ -77,7 +77,7 @@ async fn create_cron_job( udf_path: "basic:insertObject".parse()?, }; let cron_spec = CronSpec { - udf_path: path.as_root_udf_path()?.clone().canonicalize(), + udf_path: path.udf_path.clone().canonicalize(), udf_args: parse_udf_args(&path, vec![JsonValue::Object(map)])?, cron_schedule: CronSchedule::Interval { seconds: 60 }, }; diff --git a/crates/common/src/components/component_path.rs b/crates/common/src/components/component_path.rs index 32f536a4..607f0d72 100644 --- a/crates/common/src/components/component_path.rs +++ b/crates/common/src/components/component_path.rs @@ -87,6 +87,17 @@ impl ComponentPath { path.push(name); Self { path } } + + /// Returns a debug or error string to put immediately after something which + /// should be scoped to this component, + /// like `format!("'{udf_path}'{}", component_path.in_component_str())`. + pub fn in_component_str(&self) -> String { + if self.is_root() { + "".to_string() + } else { + format!(" in '{}'", String::from(self.clone())) + } + } } impl Deref for ComponentPath { diff --git a/crates/common/src/components/function_paths.rs b/crates/common/src/components/function_paths.rs index 65ce2d2d..5c72f7f0 100644 --- a/crates/common/src/components/function_paths.rs +++ b/crates/common/src/components/function_paths.rs @@ -26,11 +26,6 @@ pub struct ComponentFunctionPath { } impl ComponentFunctionPath { - pub fn as_root_udf_path(&self) -> anyhow::Result<&UdfPath> { - anyhow::ensure!(self.component.is_root()); - Ok(&self.udf_path) - } - pub fn into_root_udf_path(self) -> anyhow::Result { anyhow::ensure!(self.component.is_root()); Ok(self.udf_path) @@ -97,11 +92,6 @@ pub struct CanonicalizedComponentFunctionPath { } impl CanonicalizedComponentFunctionPath { - pub fn as_root_udf_path(&self) -> anyhow::Result<&CanonicalizedUdfPath> { - anyhow::ensure!(self.component.is_root()); - Ok(&self.udf_path) - } - pub fn into_root_udf_path(self) -> anyhow::Result { anyhow::ensure!(self.component.is_root()); Ok(self.udf_path) diff --git a/crates/isolate/src/environment/helpers/validation.rs b/crates/isolate/src/environment/helpers/validation.rs index da5b0bf7..c53f5d30 100644 --- a/crates/isolate/src/environment/helpers/validation.rs +++ b/crates/isolate/src/environment/helpers/validation.rs @@ -131,9 +131,10 @@ pub async fn validate_schedule_args( "InvalidScheduledFunction", format!( "Attempted to schedule function, but no exported function {} found in the \ - file: {}. Did you forget to export it?", + file: {}{}. Did you forget to export it?", function_name, - String::from(path.as_root_udf_path()?.module().clone()), + String::from(path.udf_path.module().clone()), + path.component.in_component_str(), ), )); } @@ -144,9 +145,10 @@ pub async fn validate_schedule_args( fn missing_or_internal_error(path: &CanonicalizedComponentFunctionPath) -> anyhow::Result { Ok(format!( - "Could not find public function for '{}'. Did you forget to run `npx convex dev` or `npx \ - convex deploy`?", - String::from(path.as_root_udf_path()?.clone().strip()) + "Could not find public function for '{}'{}. Did you forget to run `npx convex dev` or \ + `npx convex deploy`?", + String::from(path.udf_path.clone().strip()), + path.component.in_component_str() )) } @@ -414,8 +416,9 @@ impl ValidatedPathAndArgs { }, None => { anyhow::bail!( - "No visibility found for analyzed function {}", - path.as_root_udf_path()? + "No visibility found for analyzed function {}{}", + path.udf_path, + path.component.in_component_str(), ); }, }, @@ -424,8 +427,9 @@ impl ValidatedPathAndArgs { if expected_udf_type != analyzed_function.udf_type { anyhow::ensure!(path.component.is_root()); return Ok(Err(JsError::from_message(format!( - "Trying to execute {} as {}, but it is defined as {}.", - path.as_root_udf_path()?, + "Trying to execute {}{} as {}, but it is defined as {}.", + path.udf_path, + path.component.in_component_str(), expected_udf_type, analyzed_function.udf_type )))); diff --git a/crates/isolate/src/isolate2/runner.rs b/crates/isolate/src/isolate2/runner.rs index 34f2c287..a1f90235 100644 --- a/crates/isolate/src/isolate2/runner.rs +++ b/crates/isolate/src/isolate2/runner.rs @@ -486,7 +486,11 @@ async fn run_request( query_journal: QueryJournal, ) -> anyhow::Result { let (path, arguments, udf_server_version) = path_and_args.consume(); - let udf_path = path.as_root_udf_path()?; + anyhow::ensure!( + path.component.is_root(), + "TODO: non-root components not supported yet" + ); + let udf_path = &path.udf_path; // Spawn a separate Tokio thread to receive log lines. let (log_line_tx, log_line_rx) = oneshot::channel(); diff --git a/crates/isolate/src/test_helpers.rs b/crates/isolate/src/test_helpers.rs index a705bbfa..b0f4d9ed 100644 --- a/crates/isolate/src/test_helpers.rs +++ b/crates/isolate/src/test_helpers.rs @@ -569,7 +569,7 @@ impl UdfTest { }; self.database - .commit_with_write_source(tx, Some(canonicalized_path.into_root_udf_path()?.into())) + .commit_with_write_source(tx, Some(canonicalized_path.udf_path.into())) .await?; Ok(outcome) } diff --git a/crates/model/src/components/mod.rs b/crates/model/src/components/mod.rs index 4be05a0a..0ac9abf5 100644 --- a/crates/model/src/components/mod.rs +++ b/crates/model/src/components/mod.rs @@ -88,7 +88,11 @@ impl<'a, RT: Runtime> ComponentsModel<'a, RT> { .ok_or_else(|| { ErrorMetadata::bad_request( "InvalidReference", - format!("Module {:?} not found", udf_path.module()), + format!( + "Module {:?}{} not found", + udf_path.module(), + component_path.in_component_str() + ), ) })?; let analyze_result = module_metadata