@temporalio/core-bridge 1.11.1 → 1.11.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (79) hide show
  1. package/Cargo.lock +86 -88
  2. package/lib/errors.d.ts +2 -0
  3. package/lib/errors.js +5 -1
  4. package/lib/errors.js.map +1 -1
  5. package/lib/index.d.ts +3 -0
  6. package/lib/index.js.map +1 -1
  7. package/package.json +3 -3
  8. package/releases/aarch64-apple-darwin/index.node +0 -0
  9. package/releases/aarch64-unknown-linux-gnu/index.node +0 -0
  10. package/releases/x86_64-apple-darwin/index.node +0 -0
  11. package/releases/x86_64-pc-windows-msvc/index.node +0 -0
  12. package/releases/x86_64-unknown-linux-gnu/index.node +0 -0
  13. package/sdk-core/.github/workflows/per-pr.yml +7 -1
  14. package/sdk-core/Cargo.toml +1 -1
  15. package/sdk-core/client/Cargo.toml +3 -3
  16. package/sdk-core/client/src/lib.rs +1 -1
  17. package/sdk-core/client/src/metrics.rs +2 -2
  18. package/sdk-core/client/src/raw.rs +39 -13
  19. package/sdk-core/client/src/retry.rs +108 -62
  20. package/sdk-core/client/src/workflow_handle/mod.rs +1 -2
  21. package/sdk-core/core/Cargo.toml +4 -5
  22. package/sdk-core/core/src/abstractions.rs +2 -3
  23. package/sdk-core/core/src/core_tests/activity_tasks.rs +1 -1
  24. package/sdk-core/core/src/core_tests/local_activities.rs +2 -2
  25. package/sdk-core/core/src/core_tests/queries.rs +8 -4
  26. package/sdk-core/core/src/core_tests/updates.rs +2 -2
  27. package/sdk-core/core/src/core_tests/workflow_cancels.rs +3 -3
  28. package/sdk-core/core/src/core_tests/workflow_tasks.rs +55 -54
  29. package/sdk-core/core/src/ephemeral_server/mod.rs +5 -3
  30. package/sdk-core/core/src/protosext/mod.rs +3 -0
  31. package/sdk-core/core/src/telemetry/mod.rs +0 -8
  32. package/sdk-core/core/src/telemetry/otel.rs +7 -3
  33. package/sdk-core/core/src/worker/activities/activity_task_poller_stream.rs +11 -0
  34. package/sdk-core/core/src/worker/activities.rs +1 -1
  35. package/sdk-core/core/src/worker/mod.rs +6 -6
  36. package/sdk-core/core/src/worker/slot_provider.rs +4 -3
  37. package/sdk-core/core/src/worker/tuner/resource_based.rs +1 -1
  38. package/sdk-core/core/src/worker/workflow/driven_workflow.rs +28 -2
  39. package/sdk-core/core/src/worker/workflow/history_update.rs +2 -2
  40. package/sdk-core/core/src/worker/workflow/machines/activity_state_machine.rs +8 -5
  41. package/sdk-core/core/src/worker/workflow/machines/cancel_external_state_machine.rs +1 -1
  42. package/sdk-core/core/src/worker/workflow/machines/cancel_workflow_state_machine.rs +1 -1
  43. package/sdk-core/core/src/worker/workflow/machines/child_workflow_state_machine.rs +7 -7
  44. package/sdk-core/core/src/worker/workflow/machines/local_activity_state_machine.rs +10 -15
  45. package/sdk-core/core/src/worker/workflow/machines/mod.rs +1 -1
  46. package/sdk-core/core/src/worker/workflow/machines/patch_state_machine.rs +3 -2
  47. package/sdk-core/core/src/worker/workflow/machines/signal_external_state_machine.rs +1 -1
  48. package/sdk-core/core/src/worker/workflow/machines/update_state_machine.rs +4 -4
  49. package/sdk-core/core/src/worker/workflow/machines/workflow_machines.rs +30 -20
  50. package/sdk-core/core/src/worker/workflow/machines/workflow_task_state_machine.rs +2 -2
  51. package/sdk-core/core/src/worker/workflow/managed_run.rs +20 -4
  52. package/sdk-core/core/src/worker/workflow/mod.rs +33 -29
  53. package/sdk-core/core/src/worker/workflow/workflow_stream.rs +2 -2
  54. package/sdk-core/core-api/src/telemetry.rs +1 -0
  55. package/sdk-core/docker/docker-compose-telem.yaml +4 -4
  56. package/sdk-core/etc/otel-collector-config.yaml +12 -9
  57. package/sdk-core/fsm/rustfsm_procmacro/src/lib.rs +2 -2
  58. package/sdk-core/sdk/src/lib.rs +30 -3
  59. package/sdk-core/sdk/src/workflow_context.rs +15 -2
  60. package/sdk-core/sdk/src/workflow_future.rs +28 -8
  61. package/sdk-core/sdk-core-protos/protos/local/temporal/sdk/core/workflow_activation/workflow_activation.proto +31 -12
  62. package/sdk-core/sdk-core-protos/src/lib.rs +104 -63
  63. package/sdk-core/test-utils/src/lib.rs +4 -3
  64. package/sdk-core/tests/integ_tests/client_tests.rs +36 -7
  65. package/sdk-core/tests/integ_tests/heartbeat_tests.rs +1 -1
  66. package/sdk-core/tests/integ_tests/metrics_tests.rs +50 -4
  67. package/sdk-core/tests/integ_tests/queries_tests.rs +95 -62
  68. package/sdk-core/tests/integ_tests/update_tests.rs +16 -9
  69. package/sdk-core/tests/integ_tests/visibility_tests.rs +1 -1
  70. package/sdk-core/tests/integ_tests/worker_tests.rs +82 -1
  71. package/sdk-core/tests/integ_tests/workflow_tests/activities.rs +46 -8
  72. package/sdk-core/tests/integ_tests/workflow_tests/local_activities.rs +81 -2
  73. package/sdk-core/tests/integ_tests/workflow_tests/resets.rs +139 -4
  74. package/sdk-core/tests/integ_tests/workflow_tests/upsert_search_attrs.rs +43 -28
  75. package/sdk-core/tests/integ_tests/workflow_tests.rs +2 -1
  76. package/sdk-core/tests/main.rs +28 -19
  77. package/sdk-core/tests/runner.rs +7 -2
  78. package/ts/errors.ts +9 -2
  79. package/ts/index.ts +3 -0
@@ -1,9 +1,19 @@
1
+ use crate::integ_tests::activity_functions::echo;
1
2
  use futures::StreamExt;
2
- use std::{sync::Arc, time::Duration};
3
+ use std::{
4
+ sync::{
5
+ atomic::{AtomicBool, AtomicU64, Ordering},
6
+ Arc,
7
+ },
8
+ time::Duration,
9
+ };
3
10
  use temporal_client::{WfClientExt, WorkflowClientTrait, WorkflowOptions, WorkflowService};
4
- use temporal_sdk::WfContext;
5
- use temporal_sdk_core_protos::temporal::api::{
6
- common::v1::WorkflowExecution, workflowservice::v1::ResetWorkflowExecutionRequest,
11
+ use temporal_sdk::{LocalActivityOptions, WfContext};
12
+ use temporal_sdk_core_protos::{
13
+ coresdk::AsJsonPayloadExt,
14
+ temporal::api::{
15
+ common::v1::WorkflowExecution, workflowservice::v1::ResetWorkflowExecutionRequest,
16
+ },
7
17
  };
8
18
  use temporal_sdk_core_test_utils::{CoreWfStarter, NAMESPACE};
9
19
  use tokio::sync::Notify;
@@ -92,3 +102,128 @@ async fn reset_workflow() {
92
102
  let (_, rr) = tokio::join!(resetter_fut, run_fut);
93
103
  rr.unwrap();
94
104
  }
105
+
106
+ #[tokio::test]
107
+ async fn reset_randomseed() {
108
+ let wf_name = "reset_randomseed";
109
+ let mut starter = CoreWfStarter::new(wf_name);
110
+ starter.worker_config.no_remote_activities(true);
111
+ let mut worker = starter.worker().await;
112
+ worker.fetch_results = false;
113
+ let notify = Arc::new(Notify::new());
114
+
115
+ const POST_FAIL_SIG: &str = "post-fail";
116
+ static DID_FAIL: AtomicBool = AtomicBool::new(false);
117
+ static RAND_SEED: AtomicU64 = AtomicU64::new(0);
118
+
119
+ let wf_notify = notify.clone();
120
+ worker.register_wf(wf_name.to_owned(), move |ctx: WfContext| {
121
+ let notify = wf_notify.clone();
122
+ async move {
123
+ let _ = RAND_SEED.compare_exchange(
124
+ 0,
125
+ ctx.random_seed(),
126
+ Ordering::Relaxed,
127
+ Ordering::Relaxed,
128
+ );
129
+ // Make a couple workflow tasks
130
+ ctx.timer(Duration::from_millis(100)).await;
131
+ ctx.timer(Duration::from_millis(100)).await;
132
+ if DID_FAIL
133
+ .compare_exchange(false, true, Ordering::Relaxed, Ordering::Relaxed)
134
+ .is_ok()
135
+ {
136
+ // Tell outer scope to send the post-task-failure-signal
137
+ notify.notify_one();
138
+ panic!("Ahh");
139
+ }
140
+ // Make a command that is one thing with the initial seed, but another after reset
141
+ if RAND_SEED.load(Ordering::Relaxed) == ctx.random_seed() {
142
+ ctx.timer(Duration::from_millis(100)).await;
143
+ } else {
144
+ ctx.local_activity(LocalActivityOptions {
145
+ activity_type: "echo".to_string(),
146
+ input: "hi!".as_json_payload().expect("serializes fine"),
147
+ ..Default::default()
148
+ })
149
+ .await;
150
+ }
151
+ // Wait for the post-task-fail signal
152
+ let _ = ctx.make_signal_channel(POST_FAIL_SIG).next().await.unwrap();
153
+ // Tell outer scope to send the reset
154
+ notify.notify_one();
155
+ let _ = ctx
156
+ .make_signal_channel(POST_RESET_SIG)
157
+ .next()
158
+ .await
159
+ .unwrap();
160
+ Ok(().into())
161
+ }
162
+ });
163
+ worker.register_activity("echo", echo);
164
+
165
+ let run_id = worker
166
+ .submit_wf(
167
+ wf_name.to_owned(),
168
+ wf_name.to_owned(),
169
+ vec![],
170
+ WorkflowOptions::default(),
171
+ )
172
+ .await
173
+ .unwrap();
174
+
175
+ let mut client = starter.get_client().await;
176
+ let client = Arc::make_mut(&mut client);
177
+ let client_fur = async {
178
+ notify.notified().await;
179
+ WorkflowClientTrait::signal_workflow_execution(
180
+ client,
181
+ wf_name.to_owned(),
182
+ run_id.clone(),
183
+ POST_FAIL_SIG.to_string(),
184
+ None,
185
+ None,
186
+ )
187
+ .await
188
+ .unwrap();
189
+ notify.notified().await;
190
+ // Reset the workflow to be after first timer has fired
191
+ client
192
+ .reset_workflow_execution(ResetWorkflowExecutionRequest {
193
+ namespace: NAMESPACE.to_owned(),
194
+ workflow_execution: Some(WorkflowExecution {
195
+ workflow_id: wf_name.to_owned(),
196
+ run_id: run_id.clone(),
197
+ }),
198
+ workflow_task_finish_event_id: 14,
199
+ request_id: "test-req-id".to_owned(),
200
+ ..Default::default()
201
+ })
202
+ .await
203
+ .unwrap();
204
+
205
+ // Unblock the workflow by sending the signal. Run ID will have changed after reset so
206
+ // we use empty run id
207
+ WorkflowClientTrait::signal_workflow_execution(
208
+ client,
209
+ wf_name.to_owned(),
210
+ "".to_owned(),
211
+ POST_RESET_SIG.to_owned(),
212
+ None,
213
+ None,
214
+ )
215
+ .await
216
+ .unwrap();
217
+
218
+ // Wait for the now-reset workflow to finish
219
+ client
220
+ .get_untyped_workflow_handle(wf_name.to_owned(), "")
221
+ .get_workflow_result(Default::default())
222
+ .await
223
+ .unwrap();
224
+ starter.shutdown().await;
225
+ };
226
+ let run_fut = worker.run_until_done();
227
+ let (_, rr) = tokio::join!(client_fur, run_fut);
228
+ rr.unwrap();
229
+ }
@@ -1,22 +1,33 @@
1
- use std::{collections::HashMap, env};
2
- use temporal_client::{WorkflowClientTrait, WorkflowOptions};
3
- use temporal_sdk::{WfContext, WorkflowResult};
1
+ use assert_matches::assert_matches;
2
+ use std::{collections::HashMap, time::Duration};
3
+ use temporal_client::{
4
+ GetWorkflowResultOpts, WfClientExt, WorkflowClientTrait, WorkflowExecutionResult,
5
+ WorkflowOptions,
6
+ };
7
+ use temporal_sdk::{WfContext, WfExitValue, WorkflowResult};
4
8
  use temporal_sdk_core_protos::coresdk::{AsJsonPayloadExt, FromJsonPayloadExt};
5
- use temporal_sdk_core_test_utils::{CoreWfStarter, INTEG_TEMPORAL_DEV_SERVER_USED_ENV_VAR};
6
- use tracing::warn;
9
+ use temporal_sdk_core_test_utils::{CoreWfStarter, SEARCH_ATTR_INT, SEARCH_ATTR_TXT};
7
10
  use uuid::Uuid;
8
11
 
9
- // These are initialized on the server as part of the autosetup container which we
10
- // use for integration tests.
11
- static TXT_ATTR: &str = "CustomTextField";
12
- static INT_ATTR: &str = "CustomIntField";
13
-
14
12
  async fn search_attr_updater(ctx: WfContext) -> WorkflowResult<()> {
13
+ let mut int_val = ctx
14
+ .search_attributes()
15
+ .indexed_fields
16
+ .get(SEARCH_ATTR_INT)
17
+ .cloned()
18
+ .unwrap_or_default();
19
+ let orig_val = int_val.data[0];
20
+ int_val.data[0] += 1;
15
21
  ctx.upsert_search_attributes([
16
- (TXT_ATTR.to_string(), "goodbye".as_json_payload().unwrap()),
17
- (INT_ATTR.to_string(), 98.as_json_payload().unwrap()),
22
+ (SEARCH_ATTR_TXT.to_string(), "goodbye".as_json_payload()?),
23
+ (SEARCH_ATTR_INT.to_string(), int_val),
18
24
  ]);
19
- Ok(().into())
25
+ // 49 is ascii 1
26
+ if orig_val == 49 {
27
+ Ok(WfExitValue::ContinueAsNew(Box::default()))
28
+ } else {
29
+ Ok(().into())
30
+ }
20
31
  }
21
32
 
22
33
  #[tokio::test]
@@ -26,23 +37,22 @@ async fn sends_upsert() {
26
37
  let mut starter = CoreWfStarter::new(wf_name);
27
38
  starter.worker_config.no_remote_activities(true);
28
39
  let mut worker = starter.worker().await;
29
- // TODO: this should be supported in server 1.20, remove this condition when CLI is upgraded.
30
- if env::var(INTEG_TEMPORAL_DEV_SERVER_USED_ENV_VAR).is_ok() {
31
- warn!("skipping sends_upsert -- does not work on temporal dev server");
32
- return;
33
- }
34
40
 
35
41
  worker.register_wf(wf_name, search_attr_updater);
36
- let run_id = worker
42
+ worker
37
43
  .submit_wf(
38
44
  wf_id.to_string(),
39
45
  wf_name,
40
46
  vec![],
41
47
  WorkflowOptions {
42
48
  search_attributes: Some(HashMap::from([
43
- (TXT_ATTR.to_string(), "hello".as_json_payload().unwrap()),
44
- (INT_ATTR.to_string(), 1.as_json_payload().unwrap()),
49
+ (
50
+ SEARCH_ATTR_TXT.to_string(),
51
+ "hello".as_json_payload().unwrap(),
52
+ ),
53
+ (SEARCH_ATTR_INT.to_string(), 1.as_json_payload().unwrap()),
45
54
  ])),
55
+ execution_timeout: Some(Duration::from_secs(4)),
46
56
  ..Default::default()
47
57
  },
48
58
  )
@@ -50,10 +60,9 @@ async fn sends_upsert() {
50
60
  .unwrap();
51
61
  worker.run_until_done().await.unwrap();
52
62
 
53
- let search_attrs = starter
54
- .get_client()
55
- .await
56
- .describe_workflow_execution(wf_id.to_string(), Some(run_id))
63
+ let client = starter.get_client().await;
64
+ let search_attrs = client
65
+ .describe_workflow_execution(wf_id.to_string(), None)
57
66
  .await
58
67
  .unwrap()
59
68
  .workflow_execution_info
@@ -61,8 +70,8 @@ async fn sends_upsert() {
61
70
  .search_attributes
62
71
  .unwrap()
63
72
  .indexed_fields;
64
- let txt_attr_payload = search_attrs.get(TXT_ATTR).unwrap();
65
- let int_attr_payload = search_attrs.get(INT_ATTR).unwrap();
73
+ let txt_attr_payload = search_attrs.get(SEARCH_ATTR_TXT).unwrap();
74
+ let int_attr_payload = search_attrs.get(SEARCH_ATTR_INT).unwrap();
66
75
  for payload in [txt_attr_payload, int_attr_payload] {
67
76
  assert!(payload.is_json_payload());
68
77
  }
@@ -70,5 +79,11 @@ async fn sends_upsert() {
70
79
  "goodbye",
71
80
  String::from_json_payload(txt_attr_payload).unwrap()
72
81
  );
73
- assert_eq!(98, usize::from_json_payload(int_attr_payload).unwrap());
82
+ assert_eq!(3, usize::from_json_payload(int_attr_payload).unwrap());
83
+ let handle = client.get_untyped_workflow_handle(wf_id.to_string(), "");
84
+ let res = handle
85
+ .get_workflow_result(GetWorkflowResultOpts::default())
86
+ .await
87
+ .unwrap();
88
+ assert_matches!(res, WorkflowExecutionResult::Succeeded(_));
74
89
  }
@@ -79,7 +79,7 @@ async fn parallel_workflows_same_queue() {
79
79
  assert_matches!(
80
80
  task.jobs.as_slice(),
81
81
  [WorkflowActivationJob {
82
- variant: Some(workflow_activation_job::Variant::StartWorkflow(_)),
82
+ variant: Some(workflow_activation_job::Variant::InitializeWorkflow(_)),
83
83
  }]
84
84
  );
85
85
  worker
@@ -222,6 +222,7 @@ async fn fail_wf_task(#[values(true, false)] replay: bool) {
222
222
  core.complete_workflow_activation(WorkflowActivationCompletion::fail(
223
223
  task.run_id,
224
224
  Failure::application_failure("I did an oopsie".to_string(), false),
225
+ None,
225
226
  ))
226
227
  .await
227
228
  .unwrap();
@@ -19,7 +19,7 @@ mod integ_tests {
19
19
  mod worker_tests;
20
20
  mod workflow_tests;
21
21
 
22
- use std::str::FromStr;
22
+ use std::{env, str::FromStr};
23
23
  use temporal_client::WorkflowService;
24
24
  use temporal_sdk_core::{
25
25
  init_worker, ClientOptionsBuilder, ClientTlsConfig, CoreRuntime, TlsConfig,
@@ -27,9 +27,7 @@ mod integ_tests {
27
27
  };
28
28
  use temporal_sdk_core_api::worker::WorkerConfigBuilder;
29
29
  use temporal_sdk_core_protos::temporal::api::workflowservice::v1::ListNamespacesRequest;
30
- use temporal_sdk_core_test_utils::{
31
- get_integ_server_options, get_integ_telem_options, init_integ_telem,
32
- };
30
+ use temporal_sdk_core_test_utils::{get_integ_server_options, get_integ_telem_options};
33
31
  use url::Url;
34
32
 
35
33
  // Create a worker like a bridge would (unwraps aside)
@@ -61,37 +59,48 @@ mod integ_tests {
61
59
  .await;
62
60
  }
63
61
 
64
- // Manually run to verify tls works against cloud. You will need certs in place in the
65
- // indicated directory.
66
62
  #[tokio::test]
67
- #[ignore]
68
63
  async fn tls_test() {
69
- init_integ_telem();
70
- let root = tokio::fs::read("../.cloud_certs/ca.pem").await.unwrap();
71
- let client_cert = tokio::fs::read("../.cloud_certs/client.pem").await.unwrap();
72
- let client_private_key = tokio::fs::read("../.cloud_certs/client.key").await.unwrap();
64
+ let cloud_addr = env::var("TEMPORAL_CLOUD_ADDRESS");
65
+ let cloud_key = env::var("TEMPORAL_CLIENT_KEY");
66
+
67
+ let (cloud_addr, cloud_key) = if let (Ok(c), Ok(ck)) = (cloud_addr, cloud_key) {
68
+ if ck.is_empty() {
69
+ return; // secret not present in github, could be a fork, just skip
70
+ }
71
+ (c, ck)
72
+ } else {
73
+ // Skip the test
74
+ return;
75
+ };
76
+
77
+ let client_cert = env::var("TEMPORAL_CLIENT_CERT")
78
+ .expect("TEMPORAL_CLIENT_CERT must be set")
79
+ .replace("\\n", "\n")
80
+ .into_bytes();
81
+ let client_private_key = cloud_key.replace("\\n", "\n").into_bytes();
73
82
  let sgo = ClientOptionsBuilder::default()
74
- .target_url(Url::from_str("https://spencer.temporal-dev.tmprl.cloud:7233").unwrap())
83
+ .target_url(Url::from_str(&cloud_addr).unwrap())
75
84
  .client_name("tls_tester")
76
85
  .client_version("clientver")
77
86
  .tls_cfg(TlsConfig {
78
- server_root_ca_cert: Some(root),
79
- // Not necessary, but illustrates functionality for people using proxies, etc.
80
- domain: Some("spencer.temporal-dev.tmprl.cloud".to_string()),
81
87
  client_tls_config: Some(ClientTlsConfig {
82
88
  client_cert,
83
89
  client_private_key,
84
90
  }),
91
+ ..Default::default()
85
92
  })
86
93
  .build()
87
94
  .unwrap();
88
95
  let con = sgo
89
- .connect("spencer.temporal-dev".to_string(), None)
96
+ .connect(
97
+ env::var("TEMPORAL_CLOUD_NAMESPACE").expect("TEMPORAL_CLOUD_NAMESPACE must be set"),
98
+ None,
99
+ )
90
100
  .await
91
101
  .unwrap();
92
- dbg!(con
93
- .list_workflow_executions(100, vec![], "".to_string())
102
+ con.list_workflow_executions(100, vec![], "".to_string())
94
103
  .await
95
- .unwrap());
104
+ .unwrap();
96
105
  }
97
106
  }
@@ -10,7 +10,7 @@ use temporal_sdk_core::ephemeral_server::{
10
10
  };
11
11
  use temporal_sdk_core_test_utils::{
12
12
  default_cached_download, INTEG_SERVER_TARGET_ENV_VAR, INTEG_TEMPORAL_DEV_SERVER_USED_ENV_VAR,
13
- INTEG_TEST_SERVER_USED_ENV_VAR,
13
+ INTEG_TEST_SERVER_USED_ENV_VAR, SEARCH_ATTR_INT, SEARCH_ATTR_TXT,
14
14
  };
15
15
  use tokio::{self, process::Command};
16
16
 
@@ -70,11 +70,16 @@ async fn main() -> Result<(), anyhow::Error> {
70
70
  ServerKind::TemporalCLI => {
71
71
  let config = TemporalDevServerConfigBuilder::default()
72
72
  .exe(default_cached_download())
73
- // TODO: Delete when temporalCLI enables it by default.
74
73
  .extra_args(vec![
74
+ // TODO: Delete when temporalCLI enables it by default.
75
75
  "--dynamic-config-value".to_string(),
76
76
  "system.enableEagerWorkflowStart=true".to_string(),
77
+ "--search-attribute".to_string(),
78
+ format!("{SEARCH_ATTR_TXT}=Text"),
79
+ "--search-attribute".to_string(),
80
+ format!("{SEARCH_ATTR_INT}=Int"),
77
81
  ])
82
+ .ui(true)
78
83
  .build()?;
79
84
  println!("Using temporal CLI");
80
85
  (
package/ts/errors.ts CHANGED
@@ -18,7 +18,14 @@ export class TransportError extends Error {}
18
18
  * Something unexpected happened, considered fatal
19
19
  */
20
20
  @SymbolBasedInstanceOfError('UnexpectedError')
21
- export class UnexpectedError extends Error {}
21
+ export class UnexpectedError extends Error {
22
+ constructor(
23
+ message: string,
24
+ public cause?: unknown
25
+ ) {
26
+ super(message);
27
+ }
28
+ }
22
29
 
23
30
  export { IllegalStateError };
24
31
 
@@ -47,7 +54,7 @@ export function convertFromNamedError(e: unknown, keepStackTrace: boolean): unkn
47
54
  return newerr;
48
55
 
49
56
  case 'UnexpectedError':
50
- newerr = new UnexpectedError(e.message);
57
+ newerr = new UnexpectedError(e.message, e);
51
58
  newerr.stack = keepStackTrace ? e.stack : undefined;
52
59
  return newerr;
53
60
  }
package/ts/index.ts CHANGED
@@ -133,6 +133,9 @@ export interface OtelCollectorExporter {
133
133
  otel: {
134
134
  /**
135
135
  * URL of a gRPC OpenTelemetry collector.
136
+ *
137
+ * @format Starts with "grpc://" or "http://" for an unsecured connection (typical), or "grpcs://" or "https://" for a TLS connection.
138
+ * @note The `OTEL_EXPORTER_OTLP_ENDPOINT` environment variable, if set, will override this property.
136
139
  */
137
140
  url: string;
138
141
  /**