Skip to content

Commit 4fe1afe

Browse files
committed
Add tests for coro error/exception propogation.
1 parent ec69bd6 commit 4fe1afe

File tree

2 files changed

+78
-3
lines changed

2 files changed

+78
-3
lines changed

test/embind/test_val_coro.cpp

Lines changed: 58 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,24 @@ EM_JS(EM_VAL, promise_sleep_impl, (int ms, int result), {
1616
return handle;
1717
});
1818

19+
EM_JS(EM_VAL, promise_fail_impl, (), {
20+
let promise = new Promise((_, reject) => setTimeout(reject, 1, new Error("bang from JS promise!")));
21+
let handle = Emval.toHandle(promise);
22+
// FIXME. See https://github.com/emscripten-core/emscripten/issues/16975.
23+
#if __wasm64__
24+
handle = BigInt(handle);
25+
#endif
26+
return handle;
27+
});
28+
1929
val promise_sleep(int ms, int result = 0) {
2030
return val::take_ownership(promise_sleep_impl(ms, result));
2131
}
2232

33+
val promise_fail() {
34+
return val::take_ownership(promise_fail_impl());
35+
}
36+
2337
// Test that we can subclass and make custom awaitable types.
2438
template <typename T>
2539
class typed_promise: public val {
@@ -37,7 +51,13 @@ class typed_promise: public val {
3751
}
3852
};
3953

54+
template <size_t N>
4055
val asyncCoro() {
56+
co_return co_await asyncCoro<N - 1>();
57+
}
58+
59+
template <>
60+
val asyncCoro<0>() {
4161
// check that just sleeping works
4262
co_await promise_sleep(1);
4363
// check that sleeping and receiving value works
@@ -50,12 +70,48 @@ val asyncCoro() {
5070
co_return 34;
5171
}
5272

73+
template <size_t N>
5374
val throwingCoro() {
75+
co_await throwingCoro<N - 1>();
76+
co_return 56;
77+
}
78+
79+
template <>
80+
val throwingCoro<0>() {
5481
throw std::runtime_error("bang from throwingCoro!");
5582
co_return 56;
5683
}
5784

85+
template <size_t N>
86+
val failingPromise() {
87+
co_await failingPromise<N - 1>();
88+
co_return 65;
89+
}
90+
91+
template <>
92+
val failingPromise<0>() {
93+
co_await promise_fail();
94+
co_return 65;
95+
}
96+
97+
val caughtException() {
98+
int result = 0;
99+
try {
100+
co_return co_await throwingCoro<2>();
101+
} catch (const val&) { // runtime_error turns into emscripten::val
102+
result += 21;
103+
}
104+
try {
105+
co_return co_await failingPromise<2>();
106+
} catch (const val&) {
107+
result += 21;
108+
}
109+
co_return result;
110+
}
111+
58112
EMSCRIPTEN_BINDINGS(test_val_coro) {
59-
function("asyncCoro", asyncCoro);
60-
function("throwingCoro", throwingCoro);
113+
function("asyncCoro", asyncCoro<3>);
114+
function("throwingCoro", throwingCoro<3>);
115+
function("failingPromise", failingPromise<3>);
116+
function("caughtException", caughtException);
61117
}

test/test_core.py

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7485,7 +7485,7 @@ def test_embind_val_coro(self):
74857485
self.emcc_args += ['-std=c++20', '--bind', '--post-js=post.js']
74867486
self.do_runf('embind/test_val_coro.cpp', '34\n')
74877487

7488-
def test_embind_val_coro_caught(self):
7488+
def test_embind_val_coro_propogate_cpp_exception(self):
74897489
self.set_setting('EXCEPTION_STACK_TRACES')
74907490
create_file('post.js', r'''Module.onRuntimeInitialized = () => {
74917491
Module.throwingCoro().then(
@@ -7496,6 +7496,25 @@ def test_embind_val_coro_caught(self):
74967496
self.emcc_args += ['-std=c++20', '--bind', '--post-js=post.js', '-fexceptions']
74977497
self.do_runf('embind/test_val_coro.cpp', 'rejected with: std::runtime_error: bang from throwingCoro!\n')
74987498

7499+
def test_embind_val_coro_propogate_js_error(self):
7500+
self.set_setting('EXCEPTION_STACK_TRACES')
7501+
create_file('post.js', r'''Module.onRuntimeInitialized = () => {
7502+
Module.failingPromise().then(
7503+
console.log,
7504+
err => console.error(`rejected with: ${err.message}`)
7505+
);
7506+
}''')
7507+
self.emcc_args += ['-std=c++20', '--bind', '--post-js=post.js', '-fexceptions']
7508+
self.do_runf('embind/test_val_coro.cpp', 'rejected with: bang from JS promise!\n')
7509+
7510+
def test_embind_val_coro_caught_exception(self):
7511+
self.set_setting('EXCEPTION_STACK_TRACES')
7512+
create_file('post.js', r'''Module.onRuntimeInitialized = () => {
7513+
Module.caughtException().then(console.log);
7514+
}''')
7515+
self.emcc_args += ['-std=c++20', '--bind', '--post-js=post.js', '-fexceptions']
7516+
self.do_runf('embind/test_val_coro.cpp', '42\n')
7517+
74997518
def test_embind_dynamic_initialization(self):
75007519
self.emcc_args += ['-lembind']
75017520
self.do_run_in_out_file_test('embind/test_dynamic_initialization.cpp')

0 commit comments

Comments
 (0)