Skip to content

fix: better error message for missing artifacts #973

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Feb 5, 2025
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 35 additions & 2 deletions src/typegraph/core/src/utils/artifacts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,44 @@ use common::typegraph::{runtimes::Artifact, Typegraph};

pub trait ArtifactsExt {
/// update the artifact meta, and register the artifact in the typegraph
fn register_artifact(&self, artifact_path: PathBuf, tg: &mut Typegraph) -> Result<()>;
fn register_artifacts(
&self,
tg: &mut Typegraph,
entry: PathBuf,
deps: Vec<PathBuf>,
) -> Result<Vec<PathBuf>>;
}

impl ArtifactsExt for FsContext {
fn register_artifact(&self, path: PathBuf, tg: &mut Typegraph) -> Result<()> {
fn register_artifacts(
&self,
tg: &mut Typegraph,
entry: PathBuf,
deps: Vec<PathBuf>,
) -> Result<Vec<PathBuf>> {
let mut registered_deps = vec![];
self.register_artifact(tg, entry)?;
for dep in deps {
let artifacts = self.list_files(&[dep.to_string_lossy().to_string()]);
if artifacts.is_empty() {
return Err(format!(
"no artifacts found for dependency '{}'",
dep.to_string_lossy()
)
.into());
}
for artifact in artifacts.into_iter() {
self.register_artifact(tg, artifact.clone())?;
registered_deps.push(artifact);
}
}

Ok(registered_deps)
}
}

impl FsContext {
fn register_artifact(&self, tg: &mut Typegraph, path: PathBuf) -> Result<()> {
use std::collections::btree_map::Entry;
if let Entry::Vacant(entry) = tg.meta.artifacts.entry(path) {
let path = entry.key().to_path_buf();
Expand Down
12 changes: 2 additions & 10 deletions src/typegraph/core/src/utils/postprocess/deno_rt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,17 +28,9 @@ impl PostProcessor for DenoProcessor {
let mut mat_data: ModuleMatData =
object_from_map(mat_data).map_err(|e| e.to_string())?;

fs_ctx.register_artifact(mat_data.entry_point.clone(), tg)?;

let entry_point = mat_data.entry_point.clone();
let deps = std::mem::take(&mut mat_data.deps);
for artifact in deps.into_iter() {
let artifacts = fs_ctx.list_files(&[artifact.to_string_lossy().to_string()]);
for artifact in artifacts.iter() {
fs_ctx.register_artifact(artifact.clone(), tg)?;
}
mat_data.deps.extend(artifacts);
}

mat_data.deps = fs_ctx.register_artifacts(tg, entry_point, deps)?;
mat.data = map_from_object(mat_data).map_err(|e| e.to_string())?;
}
}
Expand Down
12 changes: 2 additions & 10 deletions src/typegraph/core/src/utils/postprocess/python_rt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,17 +30,9 @@ impl PostProcessor for PythonProcessor {
let mut mat_data: ModuleMatData =
object_from_map(mat_data).map_err(|e| e.to_string())?;

fs_ctx.register_artifact(mat_data.entry_point.clone(), tg)?;

let entrypoint = mat_data.entry_point.clone();
let deps = std::mem::take(&mut mat_data.deps);
for artifact in deps.into_iter() {
let artifacts = fs_ctx.list_files(&[artifact.to_string_lossy().to_string()]);
for artifact in artifacts.iter() {
fs_ctx.register_artifact(artifact.clone(), tg)?;
}
mat_data.deps.extend(artifacts);
}

mat_data.deps = fs_ctx.register_artifacts(tg, entrypoint, deps)?;
mat.data = map_from_object(mat_data).map_err(|e| e.to_string())?;
}
}
Expand Down
19 changes: 7 additions & 12 deletions src/typegraph/core/src/utils/postprocess/substantial_rt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,22 +21,17 @@ impl SubstantialProcessor {
impl PostProcessor for SubstantialProcessor {
fn postprocess(self, tg: &mut Typegraph) -> Result<(), crate::errors::TgError> {
let fs_ctx = FsContext::new(self.typegraph_dir.clone());
let runtimes = std::mem::take(&mut tg.runtimes);
let mut runtimes = std::mem::take(&mut tg.runtimes);

for runtime in runtimes.iter() {
for runtime in runtimes.iter_mut() {
if let TGRuntime::Known(known_runtime) = runtime {
match known_runtime {
runtimes::KnownRuntime::Substantial(data) => {
for wf_description in &data.workflows {
fs_ctx.register_artifact(wf_description.file.clone(), tg)?;

for artifact in &wf_description.deps {
let artifacts: Vec<PathBuf> =
fs_ctx.list_files(&[artifact.to_string_lossy().to_string()]);
for artifact in artifacts.iter() {
fs_ctx.register_artifact(artifact.clone(), tg)?;
}
}
for wf_description in &mut data.workflows {
let entrypoint = wf_description.file.clone();
let deps = std::mem::take(&mut wf_description.deps);
wf_description.deps =
fs_ctx.register_artifacts(tg, entrypoint, deps)?;
}
}
_ => continue,
Expand Down
2 changes: 1 addition & 1 deletion src/typegraph/core/src/utils/postprocess/wasm_rt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ impl PostProcessor for WasmProcessor {
}
};

fs_ctx.register_artifact(data.wasm_artifact.clone(), tg)?;
fs_ctx.register_artifacts(tg, data.wasm_artifact.clone(), vec![])?;
}

tg.runtimes = runtimes;
Expand Down
23 changes: 22 additions & 1 deletion tests/artifacts/artifacts_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,12 @@
import { Meta } from "test-utils/mod.ts";
import { join } from "@std/path/join";
import { exists } from "@std/fs/exists";
import { assert, assertFalse } from "@std/assert";
import {
assert,
assertFalse,
assertRejects,
assertStringIncludes,
} from "@std/assert";
import { connect } from "redis";
import { S3Client } from "aws-sdk/client-s3";
import { createBucket, hasObject, tryDeleteBucket } from "test-utils/s3.ts";
Expand Down Expand Up @@ -199,3 +204,19 @@ for (const { mode, ...options } of variants) {
},
);
}

Meta.test(`Missing artifact`, async (t) => {
await t.should("fail on missing artifact", async () => {
await assertRejects(
async () => {
await t.engine("runtimes/deno/inexisting_dep.py");
},
);
try {
await t.engine("runtimes/deno/inexisting_dep.py");
assert(false, "should have thrown");
} catch (e) {
assertStringIncludes(e.message, "no artifacts found for dependency");
}
});
});
25 changes: 25 additions & 0 deletions tests/runtimes/deno/inexisting_dep.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Copyright Metatype OÜ, licensed under the Mozilla Public License Version 2.0.
# SPDX-License-Identifier: MPL-2.0

from typegraph.graph.typegraph import Graph
from typegraph.policy import Policy
from typegraph.runtimes.deno import DenoRuntime

from typegraph import t, typegraph


@typegraph()
def inexisting_dep(g: Graph):
deno = DenoRuntime()
public = Policy.public()

g.expose(
public,
doAddition=deno.import_(
t.struct({"a": t.float(), "b": t.float()}),
t.float(),
module="ts/dep/main.ts",
deps=["ts/dep/nested/dep.ts", "ts/dep/nested/inexisting_dep.ts"],
name="doAddition",
),
)
Loading