Skip to content

Commit 11fc9ea

Browse files
ldanilekConvex, Inc.
authored and
Convex, Inc.
committed
Improve error messages in components (#27664)
improve error messages when printing a UDF path or module that is in a component other than the root. also reduce usage of functions `as_root_udf_path` and `into_root_udf_path` which throw a system error when given a path that's not in the root component. GitOrigin-RevId: 10689577d5fe4a10329d5f6a98ddb8299cd134ce
1 parent 5a6d356 commit 11fc9ea

File tree

9 files changed

+42
-29
lines changed

9 files changed

+42
-29
lines changed

crates/application/src/cache/mod.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -125,10 +125,9 @@ pub struct CacheKey {
125125
impl fmt::Debug for CacheKey {
126126
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
127127
let mut builder = f.debug_struct("CacheKey");
128-
if let Ok(p) = self.path.as_root_udf_path() {
129-
builder.field("path", p);
130-
}
131128
builder
129+
.field("path", &self.path.udf_path)
130+
.field("component", &self.path.component)
132131
.field("args", &self.args)
133132
.field("identity", &self.identity)
134133
.field("journal", &self.journal)

crates/application/src/lib.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1157,9 +1157,10 @@ impl<RT: Runtime> Application<RT> {
11571157
})
11581158
else {
11591159
let missing_or_internal = format!(
1160-
"Could not find function for '{}'. Did you forget to run `npx convex dev` or `npx \
1161-
convex deploy`?",
1162-
String::from(canonicalized_path.into_root_udf_path()?.strip())
1160+
"Could not find function for '{}'{}. Did you forget to run `npx convex dev` or \
1161+
`npx convex deploy`?",
1162+
String::from(canonicalized_path.udf_path.strip()),
1163+
canonicalized_path.component.in_component_str(),
11631164
);
11641165
return Ok(Err(FunctionError {
11651166
error: RedactedJsError::from_js_error(

crates/application/src/tests/cron_jobs.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ async fn create_cron_job(
7777
udf_path: "basic:insertObject".parse()?,
7878
};
7979
let cron_spec = CronSpec {
80-
udf_path: path.as_root_udf_path()?.clone().canonicalize(),
80+
udf_path: path.udf_path.clone().canonicalize(),
8181
udf_args: parse_udf_args(&path, vec![JsonValue::Object(map)])?,
8282
cron_schedule: CronSchedule::Interval { seconds: 60 },
8383
};

crates/common/src/components/component_path.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,17 @@ impl ComponentPath {
8787
path.push(name);
8888
Self { path }
8989
}
90+
91+
/// Returns a debug or error string to put immediately after something which
92+
/// should be scoped to this component,
93+
/// like `format!("'{udf_path}'{}", component_path.in_component_str())`.
94+
pub fn in_component_str(&self) -> String {
95+
if self.is_root() {
96+
"".to_string()
97+
} else {
98+
format!(" in '{}'", String::from(self.clone()))
99+
}
100+
}
90101
}
91102

92103
impl Deref for ComponentPath {

crates/common/src/components/function_paths.rs

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,6 @@ pub struct ComponentFunctionPath {
2626
}
2727

2828
impl ComponentFunctionPath {
29-
pub fn as_root_udf_path(&self) -> anyhow::Result<&UdfPath> {
30-
anyhow::ensure!(self.component.is_root());
31-
Ok(&self.udf_path)
32-
}
33-
3429
pub fn into_root_udf_path(self) -> anyhow::Result<UdfPath> {
3530
anyhow::ensure!(self.component.is_root());
3631
Ok(self.udf_path)
@@ -97,11 +92,6 @@ pub struct CanonicalizedComponentFunctionPath {
9792
}
9893

9994
impl CanonicalizedComponentFunctionPath {
100-
pub fn as_root_udf_path(&self) -> anyhow::Result<&CanonicalizedUdfPath> {
101-
anyhow::ensure!(self.component.is_root());
102-
Ok(&self.udf_path)
103-
}
104-
10595
pub fn into_root_udf_path(self) -> anyhow::Result<CanonicalizedUdfPath> {
10696
anyhow::ensure!(self.component.is_root());
10797
Ok(self.udf_path)

crates/isolate/src/environment/helpers/validation.rs

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -131,9 +131,10 @@ pub async fn validate_schedule_args<RT: Runtime>(
131131
"InvalidScheduledFunction",
132132
format!(
133133
"Attempted to schedule function, but no exported function {} found in the \
134-
file: {}. Did you forget to export it?",
134+
file: {}{}. Did you forget to export it?",
135135
function_name,
136-
String::from(path.as_root_udf_path()?.module().clone()),
136+
String::from(path.udf_path.module().clone()),
137+
path.component.in_component_str(),
137138
),
138139
));
139140
}
@@ -144,9 +145,10 @@ pub async fn validate_schedule_args<RT: Runtime>(
144145

145146
fn missing_or_internal_error(path: &CanonicalizedComponentFunctionPath) -> anyhow::Result<String> {
146147
Ok(format!(
147-
"Could not find public function for '{}'. Did you forget to run `npx convex dev` or `npx \
148-
convex deploy`?",
149-
String::from(path.as_root_udf_path()?.clone().strip())
148+
"Could not find public function for '{}'{}. Did you forget to run `npx convex dev` or \
149+
`npx convex deploy`?",
150+
String::from(path.udf_path.clone().strip()),
151+
path.component.in_component_str()
150152
))
151153
}
152154

@@ -414,8 +416,9 @@ impl ValidatedPathAndArgs {
414416
},
415417
None => {
416418
anyhow::bail!(
417-
"No visibility found for analyzed function {}",
418-
path.as_root_udf_path()?
419+
"No visibility found for analyzed function {}{}",
420+
path.udf_path,
421+
path.component.in_component_str(),
419422
);
420423
},
421424
},
@@ -424,8 +427,9 @@ impl ValidatedPathAndArgs {
424427
if expected_udf_type != analyzed_function.udf_type {
425428
anyhow::ensure!(path.component.is_root());
426429
return Ok(Err(JsError::from_message(format!(
427-
"Trying to execute {} as {}, but it is defined as {}.",
428-
path.as_root_udf_path()?,
430+
"Trying to execute {}{} as {}, but it is defined as {}.",
431+
path.udf_path,
432+
path.component.in_component_str(),
429433
expected_udf_type,
430434
analyzed_function.udf_type
431435
))));

crates/isolate/src/isolate2/runner.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -486,7 +486,11 @@ async fn run_request<RT: Runtime>(
486486
query_journal: QueryJournal,
487487
) -> anyhow::Result<UdfOutcome> {
488488
let (path, arguments, udf_server_version) = path_and_args.consume();
489-
let udf_path = path.as_root_udf_path()?;
489+
anyhow::ensure!(
490+
path.component.is_root(),
491+
"TODO: non-root components not supported yet"
492+
);
493+
let udf_path = &path.udf_path;
490494

491495
// Spawn a separate Tokio thread to receive log lines.
492496
let (log_line_tx, log_line_rx) = oneshot::channel();

crates/isolate/src/test_helpers.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -569,7 +569,7 @@ impl<RT: Runtime, P: Persistence + Clone> UdfTest<RT, P> {
569569
};
570570

571571
self.database
572-
.commit_with_write_source(tx, Some(canonicalized_path.into_root_udf_path()?.into()))
572+
.commit_with_write_source(tx, Some(canonicalized_path.udf_path.into()))
573573
.await?;
574574
Ok(outcome)
575575
}

crates/model/src/components/mod.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,11 @@ impl<'a, RT: Runtime> ComponentsModel<'a, RT> {
8888
.ok_or_else(|| {
8989
ErrorMetadata::bad_request(
9090
"InvalidReference",
91-
format!("Module {:?} not found", udf_path.module()),
91+
format!(
92+
"Module {:?}{} not found",
93+
udf_path.module(),
94+
component_path.in_component_str()
95+
),
9296
)
9397
})?;
9498
let analyze_result = module_metadata

0 commit comments

Comments
 (0)