Skip to content

Commit 11af8be

Browse files
authored
fix: Don't drop details from core errors (#705)
1 parent a66d8ed commit 11af8be

File tree

3 files changed

+22
-13
lines changed

3 files changed

+22
-13
lines changed

packages/core-bridge/src/errors.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,14 @@ pub trait CustomError {
2020
where
2121
C: Context<'a>;
2222

23-
fn from_string<'a, C>(&self, cx: &mut C, message: String) -> JsResult<'a, JsObject>
23+
fn from_string<'a, C>(&self, cx: &mut C, message: impl Into<String>) -> JsResult<'a, JsObject>
2424
where
2525
C: Context<'a>;
2626

2727
fn from_error<'a, C, E>(&self, cx: &mut C, err: E) -> JsResult<'a, JsObject>
2828
where
2929
C: Context<'a>,
30-
E: std::fmt::Display;
30+
E: std::error::Error;
3131
}
3232

3333
// Implement `CustomError` for ALL errors in a `OnceCell`. This only needs to be
@@ -46,20 +46,20 @@ impl CustomError for OnceCell<Root<JsFunction>> {
4646
error.construct(cx, args)
4747
}
4848

49-
fn from_string<'a, C>(&self, cx: &mut C, message: String) -> JsResult<'a, JsObject>
49+
fn from_string<'a, C>(&self, cx: &mut C, message: impl Into<String>) -> JsResult<'a, JsObject>
5050
where
5151
C: Context<'a>,
5252
{
53-
let args = vec![cx.string(message).upcast()];
53+
let args = vec![cx.string(message.into()).upcast()];
5454
self.construct(cx, args)
5555
}
5656

5757
fn from_error<'a, C, E>(&self, cx: &mut C, err: E) -> JsResult<'a, JsObject>
5858
where
5959
C: Context<'a>,
60-
E: std::fmt::Display,
60+
E: std::error::Error,
6161
{
62-
self.from_string(cx, format!("{}", err))
62+
self.from_string(cx, format!("{:?}", err))
6363
}
6464
}
6565

packages/core-bridge/src/lib.rs

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ use opentelemetry::trace::{FutureExt, SpanContext, TraceContextExt};
1010
use parking_lot::RwLock;
1111
use prost::Message;
1212
use std::collections::HashMap;
13+
use std::ops::Deref;
1314
use std::{
1415
cell::RefCell,
1516
fmt::Display,
@@ -90,6 +91,7 @@ enum RuntimeRequest {
9091
},
9192
}
9293

94+
#[derive(Debug)]
9395
enum WorkerRequest {
9496
/// A request to shutdown a worker, the worker instance will remain active to
9597
/// allow draining of pending tasks
@@ -287,7 +289,7 @@ fn start_bridge_loop(channel: Arc<Channel>, receiver: &mut UnboundedReceiver<Run
287289
Err(err) => {
288290
send_error(channel.clone(), callback, |cx| match err {
289291
ClientInitError::SystemInfoCallError(e) => TRANSPORT_ERROR
290-
.from_error(
292+
.from_string(
291293
cx,
292294
format!("Failed to call GetSystemInfo: {}", e),
293295
),
@@ -364,8 +366,8 @@ fn start_bridge_loop(channel: Arc<Channel>, receiver: &mut UnboundedReceiver<Run
364366
Ok(cx.boxed(RefCell::new(Some(WorkerHandle { sender: tx }))))
365367
})
366368
}
367-
Err(err) => send_error(channel.clone(), callback, |cx| {
368-
UNEXPECTED_ERROR.from_error(cx, err)
369+
Err(err) => send_error(channel.clone(), callback, move |cx| {
370+
UNEXPECTED_ERROR.from_error(cx, err.deref())
369371
}),
370372
};
371373
}
@@ -826,7 +828,7 @@ fn worker_record_activity_heartbeat(mut cx: FunctionContext) -> JsResult<JsUndef
826828
let heartbeat = cx.argument::<JsArrayBuffer>(1)?;
827829
match &*worker.borrow() {
828830
None => UNEXPECTED_ERROR
829-
.from_error(&mut cx, "Tried to use closed Worker")
831+
.from_string(&mut cx, "Tried to use closed Worker")
830832
.and_then(|err| cx.throw(err))?,
831833
Some(worker) => {
832834
match ActivityHeartbeat::decode_length_delimited(heartbeat.as_slice(&mut cx)) {
@@ -873,7 +875,7 @@ fn worker_finalize_shutdown(mut cx: FunctionContext) -> JsResult<JsUndefined> {
873875
let worker = cx.argument::<BoxedWorker>(0)?;
874876
if worker.replace(None).is_none() {
875877
ILLEGAL_STATE_ERROR
876-
.from_error(&mut cx, "Worker already closed")
878+
.from_string(&mut cx, "Worker already closed")
877879
.and_then(|err| cx.throw(err))?;
878880
}
879881

@@ -885,7 +887,7 @@ fn client_close(mut cx: FunctionContext) -> JsResult<JsUndefined> {
885887
let client = cx.argument::<BoxedClient>(0)?;
886888
if client.replace(None).is_none() {
887889
ILLEGAL_STATE_ERROR
888-
.from_error(&mut cx, "Client already closed")
890+
.from_string(&mut cx, "Client already closed")
889891
.and_then(|err| cx.throw(err))?;
890892
};
891893
Ok(cx.undefined())

packages/test/src/test-native-connection.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import test from 'ava';
22

3-
import { IllegalStateError, NativeConnection, Worker } from '@temporalio/worker';
3+
import { IllegalStateError, NativeConnection, TransportError, Worker } from '@temporalio/worker';
44
import { RUN_INTEGRATION_TESTS } from './helpers';
55

66
test('NativeConnection.connect() throws meaningful error when passed invalid address', async (t) => {
@@ -18,6 +18,13 @@ test('NativeConnection.connect() throws meaningful error when passed invalid cli
1818
});
1919

2020
if (RUN_INTEGRATION_TESTS) {
21+
test('NativeConnection errors have detail', async (t) => {
22+
await t.throwsAsync(() => NativeConnection.connect({ address: 'localhost:1' }), {
23+
instanceOf: TransportError,
24+
message: /.*Connection refused.*/,
25+
});
26+
});
27+
2128
test('NativeConnection.close() throws when called a second time', async (t) => {
2229
const conn = await NativeConnection.connect();
2330
await conn.close();

0 commit comments

Comments
 (0)