Skip to content

Commit 99c3af9

Browse files
committed
feat: adjustments from code review
1 parent 58b945d commit 99c3af9

8 files changed

Lines changed: 59 additions & 52 deletions

File tree

crates/taurus-core/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,6 @@
55
66
mod handler;
77
pub mod runtime;
8+
pub mod time;
89
pub mod types;
910
pub mod value;

crates/taurus-core/src/runtime/engine.rs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -170,8 +170,8 @@ mod tests {
170170
use crate::types::exit_reason::ExitReason;
171171
use std::cell::RefCell;
172172
use tucana::shared::{
173-
InputType, ListValue, NodeParameter, NodeValue, ReferenceValue, Struct, Value, node_value,
174-
reference_value, value::Kind,
173+
InputType, ListValue, NodeParameter, NodeValue, ReferenceValue, Struct, SubFlow, Value,
174+
node_value, reference_value, sub_flow::ExecutionReference, value::Kind,
175175
};
176176

177177
fn literal_param(database_id: i64, runtime_parameter_id: &str, value: Value) -> NodeParameter {
@@ -190,9 +190,11 @@ mod tests {
190190
database_id,
191191
runtime_parameter_id: runtime_parameter_id.to_string(),
192192
value: Some(NodeValue {
193-
value: Some(node_value::Value::SubFlow(unimplemented!(
194-
"Taurus needs to handle SubFlows (issue nr #184)"
195-
))),
193+
value: Some(node_value::Value::SubFlow(SubFlow {
194+
signature: String::new(),
195+
settings: Vec::new(),
196+
execution_reference: Some(ExecutionReference::StartingNodeId(node_id)),
197+
})),
196198
}),
197199
cast: None,
198200
}

crates/taurus-core/src/runtime/execution/value_store.rs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
//! Mutable value store used by runtime execution to resolve references.
22
33
use std::collections::HashMap;
4-
use std::time::{SystemTime, UNIX_EPOCH};
54

65
use tucana::shared::node_execution_result::Result as TucanaNodeResult;
76
use tucana::shared::{InputType, NodeExecutionResult, ReferenceValue, Value, value::Kind};
87

98
use crate::runtime::execution::trace::{StoreInputSlotEntry, StoreResultEntry, StoreSnapshot};
9+
use crate::time::now_unix_ms;
1010
use crate::types::errors::runtime_error::RuntimeError;
1111

1212
#[derive(Clone)]
@@ -106,7 +106,14 @@ impl ValueStore {
106106
Some(TucanaNodeResult::Error(error)) => {
107107
ValueStoreResult::Error(RuntimeError::from_tucana_error(error))
108108
}
109-
None => ValueStoreResult::NotFound,
109+
None => ValueStoreResult::Error(RuntimeError::new(
110+
"T-CORE-000006",
111+
"NodeExecutionResultMissingOutcome",
112+
format!(
113+
"Node {} execution result is missing success/error outcome",
114+
id
115+
),
116+
)),
110117
},
111118
None => ValueStoreResult::NotFound,
112119
}
@@ -214,13 +221,6 @@ impl ValueStore {
214221
}
215222
}
216223

217-
fn now_unix_ms() -> i64 {
218-
SystemTime::now()
219-
.duration_since(UNIX_EPOCH)
220-
.map(|it| it.as_millis() as i64)
221-
.unwrap_or(0)
222-
}
223-
224224
fn preview_value(value: &Value) -> String {
225225
match value.kind.as_ref() {
226226
Some(Kind::NumberValue(v)) => crate::value::number_to_string(v),

crates/taurus-core/src/time.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
//! Shared time helpers for runtime metadata.
2+
3+
use std::time::{SystemTime, UNIX_EPOCH};
4+
5+
pub fn now_unix_ms() -> i64 {
6+
SystemTime::now()
7+
.duration_since(UNIX_EPOCH)
8+
.map(|it| it.as_millis() as i64)
9+
.unwrap_or(0)
10+
}

crates/taurus-core/src/types/errors/runtime_error.rs

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,14 @@
99
use std::collections::HashMap;
1010
use std::error::Error;
1111
use std::fmt::{Display, Formatter};
12-
use std::time::{SystemTime, UNIX_EPOCH};
1312

1413
use tucana::shared::value::Kind::{NumberValue, StringValue, StructValue};
1514
use tucana::shared::{
1615
Error as TucanaError, NumberValue as ProtoNumberValue, Struct, Value, number_value,
1716
};
1817

18+
use crate::time::now_unix_ms;
19+
1920
/// Runtime execution failure representation.
2021
#[derive(Debug, Clone, PartialEq)]
2122
pub struct RuntimeError {
@@ -46,7 +47,7 @@ impl RuntimeError {
4647
code: code.into(),
4748
category: category.into(),
4849
message: message.into(),
49-
timestamp_unix_ms: now_unix_ms(),
50+
timestamp_unix_ms: now_unix_ms() as u64,
5051
version: env!("CARGO_PKG_VERSION").to_string(),
5152
dependencies: HashMap::new(),
5253
details: HashMap::new(),
@@ -189,10 +190,3 @@ impl Display for RuntimeError {
189190
write!(f, "[{}] {}: {}", self.code, self.category, self.message)
190191
}
191192
}
192-
193-
fn now_unix_ms() -> u64 {
194-
SystemTime::now()
195-
.duration_since(UNIX_EPOCH)
196-
.map(|it| it.as_millis() as u64)
197-
.unwrap_or(0)
198-
}

crates/taurus-provider/src/providers/remote/nats_remote_runtime.rs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -34,12 +34,12 @@ impl RemoteRuntime for NATSRemoteRuntime {
3434
Ok(r) => r,
3535
Err(err) => {
3636
log::error!(
37-
"RemoteRuntimeExeption: failed to handle NATS message: {}",
37+
"RemoteRuntimeException: failed to handle NATS message: {}",
3838
err
3939
);
4040
return Err(RuntimeError::new(
4141
"T-PROV-000001",
42-
"RemoteRuntimeExeption",
42+
"RemoteRuntimeException",
4343
"Failed to receive any response messages from a remote runtime.",
4444
));
4545
}
@@ -50,22 +50,22 @@ impl RemoteRuntime for NATSRemoteRuntime {
5050
Ok(r) => match r.node_result {
5151
Some(res) => Ok(res),
5252
None => {
53-
log::error!("RemoteRuntimeExeption: recieved execution result without an body");
54-
return Err(RuntimeError::new(
53+
log::error!("RemoteRuntimeException: received execution result without a body");
54+
Err(RuntimeError::new(
5555
"T-PROV-000003",
56-
"RemoteRuntimeExeption",
57-
"Recieved empty action execution response",
58-
));
56+
"RemoteRuntimeException",
57+
"Received empty action execution response",
58+
))
5959
}
6060
},
6161
Err(err) => {
6262
log::error!(
63-
"RemoteRuntimeExeption: failed to decode NATS message: {}",
63+
"RemoteRuntimeException: failed to decode NATS message: {}",
6464
err
6565
);
6666
return Err(RuntimeError::new(
6767
"T-PROV-000002",
68-
"RemoteRuntimeExeption",
68+
"RemoteRuntimeException",
6969
"Failed to read Remote Response",
7070
));
7171
}

crates/taurus/src/app/worker.rs

Lines changed: 15 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
use std::time::Instant;
2-
use std::time::{SystemTime, UNIX_EPOCH};
32

43
use futures_lite::StreamExt;
54
use prost::Message;
65
use taurus_core::runtime::engine::{EmitType, ExecutionEngine, ExecutionId, RespondEmitter};
6+
use taurus_core::time::now_unix_ms;
77
use taurus_core::types::errors::runtime_error::RuntimeError;
88
use taurus_core::types::signal::Signal;
99
use taurus_provider::providers::emitter::nats_emitter::NATSRespondEmitter;
@@ -37,15 +37,15 @@ pub fn spawn_worker(
3737
};
3838

3939
let mut test_execution_subscription = match client
40-
.queue_subscribe(String::from("test_executions.*"), "taurus".into())
40+
.queue_subscribe(String::from("test_execution.*"), "taurus".into())
4141
.await
4242
{
4343
Ok(subscription) => {
44-
log::info!("Subscribed to 'test_executions.*'");
44+
log::info!("Subscribed to 'test_execution.*'");
4545
subscription
4646
}
4747
Err(err) => {
48-
log::error!("Failed to subscribe to 'test_executions.*': {:?}", err);
48+
log::error!("Failed to subscribe to 'test_execution.*': {:?}", err);
4949
return;
5050
}
5151
};
@@ -85,7 +85,7 @@ pub fn spawn_worker(
8585
}
8686
None => {
8787
test_execution_closed = true;
88-
log::warn!("Subscription 'test_executions.*' ended");
88+
log::warn!("Subscription 'test_execution.*' ended");
8989
}
9090
}
9191
}
@@ -158,8 +158,16 @@ async fn process_test_execution_message(
158158
nats_remote: &NATSRemoteRuntime,
159159
runtime_usage_service: Option<&TaurusRuntimeUsageService>,
160160
) {
161+
if message.reply.is_none() {
162+
log::warn!(
163+
"Received test execution request without reply subject on '{}'; ignoring request",
164+
message.subject
165+
);
166+
return;
167+
}
168+
161169
let requested_execution_id =
162-
match parse_execution_id_from_subject(&message.subject, "test_executions") {
170+
match parse_execution_id_from_subject(&message.subject, "test_execution") {
163171
Some(res) => res,
164172
None => {
165173
log::error!("Failed to extract execution uuid from {}", &message.subject);
@@ -335,13 +343,6 @@ async fn respond_to_test_execution_request(
335343
}
336344
}
337345

338-
fn now_unix_ms() -> i64 {
339-
SystemTime::now()
340-
.duration_since(UNIX_EPOCH)
341-
.map(|it| it.as_millis() as i64)
342-
.unwrap_or(0)
343-
}
344-
345346
#[cfg(test)]
346347
mod tests {
347348
use super::*;
@@ -381,7 +382,6 @@ mod tests {
381382
runtime().block_on(async {
382383
let client = connect_test_nats().await;
383384
let worker = spawn_test_worker(client.clone());
384-
wait_for_worker_subscription().await;
385385

386386
let execution_id = ExecutionId::new_v4();
387387
let fixture = load_fixture("flows/01_return_object.json");
@@ -418,7 +418,6 @@ mod tests {
418418
runtime().block_on(async {
419419
let client = connect_test_nats().await;
420420
let worker = spawn_test_worker(client.clone());
421-
wait_for_worker_subscription().await;
422421

423422
let execution_id = ExecutionId::new_v4();
424423
let response =
@@ -471,16 +470,12 @@ mod tests {
471470
spawn_worker(client, engine, nats_remote, runtime_emitter, None)
472471
}
473472

474-
async fn wait_for_worker_subscription() {
475-
tokio::time::sleep(Duration::from_millis(250)).await;
476-
}
477-
478473
async fn request_execution_result(
479474
client: &async_nats::Client,
480475
execution_id: ExecutionId,
481476
payload: Vec<u8>,
482477
) -> Result<ExecutionResult, String> {
483-
let subject = format!("test_executions.{execution_id}");
478+
let subject = format!("test_execution.{execution_id}");
484479

485480
for attempt in 1..=10 {
486481
match tokio::time::timeout(

docs/errors.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ This document is the canonical catalog for runtime error codes emitted by Taurus
1010

1111
- `T-STD-XXXXX`: Errors originating inside standard function implementations under `runtime/functions/*`.
1212
- `T-CORE-XXXXXX`: Errors originating from core runtime infrastructure.
13+
- `T-TAURUS-XXXXXX`: Errors originating from the Taurus runtime app layer.
1314
- `T-PROV-XXXXXX`: Errors originating from provider integrations (transport adapters, remote runtime connectors).
1415

1516
## Code Table
@@ -23,10 +24,13 @@ This document is the canonical catalog for runtime error codes emitted by Taurus
2324
| `T-CORE-000003` | Engine | Flow requires remote execution but no remote runtime adapter was configured. | Node execution target is remote while `RemoteRuntime` is `None`. | `runtime/engine/executor.rs` |
2425
| `T-CORE-000004` | Engine | Reference lookup failed in the execution value store. | Missing prior node result, missing flow input path, or unresolved input reference. | `runtime/engine/executor.rs` |
2526
| `T-CORE-000005` | Engine | Remote request cannot be assembled because parameter metadata and resolved values diverge. | Parameter count mismatch during remote request materialization. | `runtime/engine/executor.rs` |
27+
| `T-CORE-000006` | Engine | Node execution result exists without a success/error outcome. | Provider or value store returned a `NodeExecutionResult` with no `result` field. | `runtime/engine/executor.rs`, `runtime/execution/value_store.rs` |
2628
| `T-CORE-000101` | Compiler | Flow compilation failed because a node id appears more than once. | Duplicate `database_id` in input nodes. | `runtime/engine/compiler.rs` |
2729
| `T-CORE-000102` | Compiler | Flow compilation failed because the declared start node is absent. | `start_node_id` not found in node list. | `runtime/engine/compiler.rs` |
2830
| `T-CORE-000103` | Compiler | Flow compilation failed because a `next` edge points to a missing node. | `next_node_id` references unknown node id. | `runtime/engine/compiler.rs` |
2931
| `T-CORE-000104` | Compiler | Flow compilation failed because a parameter is structurally incomplete. | Parameter has no value payload in IR. | `runtime/engine/compiler.rs` |
32+
| `T-CORE-000105` | Compiler | Flow compilation failed because a sub-flow parameter is missing its execution reference. | `sub_flow.execution_reference` is absent. | `runtime/engine/compiler.rs` |
33+
| `T-CORE-000106` | Compiler | Flow compilation failed because a sub-flow parameter uses an unsupported execution reference. | `sub_flow.execution_reference` is not a starting node id. | `runtime/engine/compiler.rs` |
3034
| `T-CORE-000201` | Handler | Handler argument arity contract was violated before function execution began. | `args!`/`no_args!` macro expected different argument count. | `handler/macros.rs` |
3135
| `T-CORE-000202` | Handler | Handler argument type conversion failed during typed extraction. | `TryFromArgument` expected type does not match provided argument. | `handler/argument.rs` |
3236
| `T-CORE-000301` | App Error Mapping | Application configuration failure mapped into runtime error format. | Invalid/missing runtime config surfaced as `Error::Configuration`. | `types/errors/error.rs` |
@@ -35,6 +39,7 @@ This document is the canonical catalog for runtime error codes emitted by Taurus
3539
| `T-CORE-000304` | App Error Mapping | Serialization/deserialization failure mapped into runtime error format. | Encoding/decoding/parsing failure surfaced as `Error::Serialization`. | `types/errors/error.rs` |
3640
| `T-CORE-000399` | App Error Mapping | Internal application failure mapped into runtime error format. | Catch-all non-domain internal failure surfaced as `Error::Internal`. | `types/errors/error.rs` |
3741
| `T-CORE-999999` | Runtime Error Fallback | Default fallback runtime error code when no explicit mapping is provided. | `RuntimeError::default()` used as defensive fallback. | `types/errors/runtime_error.rs` |
42+
| `T-TAURUS-000001` | Taurus App | Test execution request payload could not be decoded as an execution flow. | Malformed or schema-incompatible payload published to the test execution NATS subject. | `taurus/src/app/worker.rs` |
3843
| `T-PROV-000001` | Provider Remote Runtime | Remote request to NATS did not yield a valid response message. | NATS request failed or timed out while waiting for remote runtime answer. | `taurus-provider/providers/remote/nats_remote_runtime.rs` |
3944
| `T-PROV-000002` | Provider Remote Runtime | Remote runtime response could not be decoded into expected protobuf structure. | Received payload is malformed, truncated, or schema-incompatible for `ExecutionResult`. | `taurus-provider/providers/remote/nats_remote_runtime.rs` |
4045
| `T-PROV-000003` | Provider Remote Runtime | Remote runtime response decoded, but contained no concrete result field. | `ExecutionResult` exists but `result` is `None` (protocol contract violation). | `taurus-provider/providers/remote/nats_remote_runtime.rs` |

0 commit comments

Comments
 (0)