Skip to content

Commit fcde9f1

Browse files
committed
optionally return non-zero error code when function run sees error
1 parent fb95108 commit fcde9f1

File tree

7 files changed

+110
-1
lines changed

7 files changed

+110
-1
lines changed

src/engine.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,7 @@ pub fn run(params: FunctionRunParams) -> Result<FunctionRunResult> {
234234
output,
235235
profile: profile_data,
236236
scale_factor,
237+
success: error_logs.is_empty(),
237238
};
238239

239240
Ok(function_run_result)

src/function_run_result.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ pub struct FunctionRunResult {
3030
pub profile: Option<String>,
3131
#[serde(skip)]
3232
pub scale_factor: f64,
33+
pub success: bool,
3334
}
3435

3536
const DEFAULT_INSTRUCTIONS_LIMIT: u64 = 11_000_000;
@@ -253,6 +254,7 @@ mod tests {
253254
})),
254255
profile: None,
255256
scale_factor: 1.0,
257+
success: true,
256258
};
257259

258260
let predicate = predicates::str::contains("Instructions: 1.001K")
@@ -284,6 +286,7 @@ mod tests {
284286
})),
285287
profile: None,
286288
scale_factor: 1.0,
289+
success: true,
287290
};
288291

289292
let predicate = predicates::str::contains("Instructions: 1")
@@ -311,6 +314,7 @@ mod tests {
311314
})),
312315
profile: None,
313316
scale_factor: 1.0,
317+
success: true,
314318
};
315319

316320
let predicate = predicates::str::contains("Instructions: 999")

src/main.rs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,10 @@ struct Opts {
7272
/// Path to graphql file containing Function input query; if omitted, defaults will be used to calculate limits.
7373
#[clap(short = 'q', long)]
7474
query_path: Option<PathBuf>,
75+
76+
/// Return a non-zero exit code when a module error occurs during the function run.
77+
#[clap(short = 'n', long)]
78+
non_zero_exit_code_for_module_errors: bool,
7579
}
7680

7781
impl Opts {
@@ -196,5 +200,11 @@ fn main() -> Result<()> {
196200
std::fs::write(profile_opts.unwrap().out, profile)?;
197201
}
198202

199-
Ok(())
203+
if function_run_result.success || !opts.non_zero_exit_code_for_module_errors {
204+
Ok(())
205+
} else {
206+
Err(anyhow!(
207+
"The Function execution failed. Review the logs for more information."
208+
))
209+
}
200210
}

tests/fixtures/README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,11 @@ js_functions_javy_v1.wasm:
3131
javy build -C dynamic -C plugin=providers/shopify_functions_javy_v1.wasm -o tests/fixtures/build/js_functions_javy_v1.wasm tests/fixtures/js_function/src/functions.js
3232
```
3333

34+
js_function_that_throws.wasm:
35+
```
36+
javy build -C dynamic -C plugin=providers/javy_quickjs_provider_v3.wasm -o tests/fixtures/build/js_function_that_throws.wasm tests/fixtures/js_function_that_throws/src/functions.js
37+
```
38+
3439
**`*.wat` examples:**
3540
```
3641
find tests/fixtures -maxdepth 1 -type f -name "*.wat" \
2.65 KB
Binary file not shown.
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
var __defProp = Object.defineProperty;
2+
var __export = (target, all) => {
3+
for (var name in all)
4+
__defProp(target, name, { get: all[name], enumerable: true });
5+
};
6+
7+
// node_modules/javy/dist/fs/index.js
8+
var o = /* @__PURE__ */ ((r) => (r[r.Stdin = 0] = "Stdin", r[r.Stdout = 1] = "Stdout", r[r.Stderr = 2] = "Stderr", r))(o || {});
9+
function a(r) {
10+
let e = new Uint8Array(1024), t = 0;
11+
for (; ;) {
12+
const i = Javy.IO.readSync(r, e.subarray(t));
13+
if (i < 0)
14+
throw Error("Error while reading from file descriptor");
15+
if (i === 0)
16+
return e.subarray(0, t + i);
17+
if (t += i, t === e.length) {
18+
const n = new Uint8Array(e.length * 2);
19+
n.set(e), e = n;
20+
}
21+
}
22+
}
23+
function s(r, e) {
24+
for (; e.length > 0;) {
25+
const t = Javy.IO.writeSync(r, e);
26+
if (t < 0)
27+
throw Error("Error while writing to file descriptor");
28+
e = e.subarray(t);
29+
}
30+
}
31+
32+
// extensions/volume-js/src/index.js
33+
var src_exports = {};
34+
__export(src_exports, {
35+
default: () => src_default
36+
});
37+
var EMPTY_DISCOUNT = {
38+
discountApplicationStrategy: "FIRST" /* First */,
39+
discounts: []
40+
};
41+
var src_default = (input) => {
42+
throw Error("A problem occurred.")
43+
};
44+
45+
// node_modules/@shopify/shopify_function/index.ts
46+
var input_data = a(o.Stdin);
47+
var input_str = new TextDecoder("utf-8").decode(input_data);
48+
var input_obj = JSON.parse(input_str);
49+
var output_obj = src_exports?.default(input_obj);
50+
var output_str = JSON.stringify(output_obj);
51+
var output_data = new TextEncoder().encode(output_str);
52+
s(o.Stdout, output_data);

tests/integration_tests.rs

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,43 @@ mod tests {
221221
Ok(())
222222
}
223223

224+
#[test]
225+
fn failing_function_without_non_zero_exit_code_for_module_errors_flag(
226+
) -> Result<(), Box<dyn std::error::Error>> {
227+
let mut cmd = Command::cargo_bin("function-runner")?;
228+
let input_file = temp_input(json!({}))?;
229+
cmd.args([
230+
"--function",
231+
"tests/fixtures/build/js_function_that_throws.wasm",
232+
])
233+
.arg("--input")
234+
.arg(input_file.as_os_str());
235+
236+
cmd.assert().success();
237+
238+
Ok(())
239+
}
240+
241+
#[test]
242+
fn failing_function_with_non_zero_exit_code_for_module_errors_flag(
243+
) -> Result<(), Box<dyn std::error::Error>> {
244+
let mut cmd = Command::cargo_bin("function-runner")?;
245+
let input_file = temp_input(json!({}))?;
246+
cmd.args([
247+
"--function",
248+
"tests/fixtures/build/js_function_that_throws.wasm",
249+
])
250+
.arg("--non-zero-exit-code-for-module-errors")
251+
.arg("--input")
252+
.arg(input_file.as_os_str());
253+
254+
cmd.assert().failure().stderr(contains(
255+
"The Function execution failed. Review the logs for more information.",
256+
));
257+
258+
Ok(())
259+
}
260+
224261
fn profile_base_cmd_in_temp_dir(
225262
) -> Result<(Command, assert_fs::TempDir), Box<dyn std::error::Error>> {
226263
let mut cmd = Command::cargo_bin("function-runner")?;

0 commit comments

Comments
 (0)