Skip to content

Commit 8b1364e

Browse files
committed
fix(rivetkit-core): preserve user error metadata
1 parent a04f44b commit 8b1364e

6 files changed

Lines changed: 50 additions & 3 deletions

File tree

rivetkit-rust/packages/rivetkit-core/src/error.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use serde_json::Value as JsonValue;
44

55
pub fn public_error_status_code(group: &str, code: &str) -> Option<u16> {
66
match (group, code) {
7+
("user", _) => Some(400),
78
("auth", "forbidden") => Some(403),
89
("actor", "action_not_found") => Some(404),
910
("actor", "action_timed_out") => Some(408),

rivetkit-rust/packages/rivetkit-core/tests/context.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -327,6 +327,7 @@ mod moved_tests {
327327
)),
328328
protocol_metadata: Arc::new(tokio::sync::Mutex::new(None)),
329329
shutting_down: std::sync::atomic::AtomicBool::new(false),
330+
last_ping_ts: std::sync::atomic::AtomicI64::new(now_timestamp_ms()),
330331
stopped_tx: tokio::sync::watch::channel(true).0,
331332
});
332333
shared
@@ -373,6 +374,7 @@ mod moved_tests {
373374
)),
374375
protocol_metadata: Arc::new(tokio::sync::Mutex::new(None)),
375376
shutting_down: std::sync::atomic::AtomicBool::new(false),
377+
last_ping_ts: std::sync::atomic::AtomicI64::new(now_timestamp_ms()),
376378
stopped_tx: tokio::sync::watch::channel(true).0,
377379
});
378380
EnvoyHandle::from_shared(shared)

rivetkit-rust/packages/rivetkit-core/tests/modules/action_dispatch_error.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,29 @@ fn preserves_public_error_message_for_client_boundary() {
2929
assert_eq!(error.client_message(), "action `missing` was not found");
3030
}
3131

32+
#[test]
33+
fn preserves_user_error_message_and_metadata_for_client_boundary() {
34+
let metadata = serde_json::json!({
35+
"limit": 20,
36+
"attempted": 25,
37+
});
38+
let error = ActionDispatchError::from_anyhow(anyhow::Error::new(RivetError {
39+
kind: RivetErrorKind::Dynamic {
40+
group: "user".to_owned(),
41+
code: "quota_exceeded".to_owned(),
42+
default_message: "quota exceeded".to_owned(),
43+
},
44+
meta: serde_json::value::to_raw_value(&metadata).ok(),
45+
message: None,
46+
actor: None,
47+
}));
48+
49+
assert_eq!(error.group, "user");
50+
assert_eq!(error.code, "quota_exceeded");
51+
assert_eq!(error.client_message(), "quota exceeded");
52+
assert_eq!(error.client_metadata(), Some(&metadata));
53+
}
54+
3255
#[test]
3356
fn masks_private_structured_message_at_client_boundary() {
3457
static TEST_ERROR: RivetErrorSchema = RivetErrorSchema {

rivetkit-rust/packages/rivetkit-core/tests/schedule.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ mod moved_tests {
9696
)),
9797
protocol_metadata: Arc::new(tokio::sync::Mutex::new(None)),
9898
shutting_down: AtomicBool::new(false),
99+
last_ping_ts: std::sync::atomic::AtomicI64::new(now_timestamp_ms()),
99100
stopped_tx: tokio::sync::watch::channel(true).0,
100101
});
101102

rivetkit-rust/packages/rivetkit-core/tests/sqlite.rs

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
use std::collections::HashMap;
22
use std::sync::Arc;
3-
use std::sync::atomic::AtomicBool;
43
use std::sync::Mutex as StdMutex;
4+
use std::sync::atomic::AtomicBool;
5+
use std::time::{SystemTime, UNIX_EPOCH};
56

67
use super::*;
78
use depot_client_types::{HEAD_FENCE_MISMATCH_CODE, HEAD_FENCE_MISMATCH_GROUP};
@@ -34,6 +35,13 @@ struct SqliteOperationLog {
3435
error_message: Option<String>,
3536
}
3637

38+
fn now_timestamp_ms() -> i64 {
39+
let duration = SystemTime::now()
40+
.duration_since(UNIX_EPOCH)
41+
.unwrap_or_default();
42+
i64::try_from(duration.as_millis()).unwrap_or(i64::MAX)
43+
}
44+
3745
#[derive(Clone)]
3846
struct SqliteOperationLogLayer {
3947
records: Arc<StdMutex<Vec<SqliteOperationLog>>>,
@@ -173,6 +181,7 @@ fn test_envoy_handle() -> (EnvoyHandle, mpsc::UnboundedReceiver<ToEnvoyMessage>)
173181
ws_tx: Arc::new(AsyncMutex::new(None::<mpsc::UnboundedSender<WsTxMessage>>)),
174182
protocol_metadata: Arc::new(AsyncMutex::new(None)),
175183
shutting_down: AtomicBool::new(false),
184+
last_ping_ts: std::sync::atomic::AtomicI64::new(now_timestamp_ms()),
176185
stopped_tx: tokio::sync::watch::channel(true).0,
177186
});
178187

@@ -318,7 +327,10 @@ async fn remote_execute_logs_operation_context_at_source() {
318327
let result = db
319328
.execute(
320329
"SELECT ?",
321-
Some(vec![BindParam::Integer(1), BindParam::Text("two".to_owned())]),
330+
Some(vec![
331+
BindParam::Integer(1),
332+
BindParam::Text("two".to_owned()),
333+
]),
322334
)
323335
.await;
324336

rivetkit-rust/packages/rivetkit-core/tests/task.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ mod moved_tests {
66
use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering};
77
use std::sync::{Mutex, OnceLock};
88
use std::task::Poll;
9-
use std::time::{Duration, Instant};
9+
use std::time::{Duration, Instant, SystemTime, UNIX_EPOCH};
1010

1111
use futures::{FutureExt, poll};
1212
use rivet_envoy_client::config::{
@@ -52,6 +52,13 @@ mod moved_tests {
5252
use crate::{ActorConfig, ActorContext, ActorFactory};
5353
use rivet_envoy_client::utils::EnvoyShutdownError;
5454

55+
fn now_timestamp_ms() -> i64 {
56+
let duration = SystemTime::now()
57+
.duration_since(UNIX_EPOCH)
58+
.unwrap_or_default();
59+
i64::try_from(duration.as_millis()).unwrap_or(i64::MAX)
60+
}
61+
5562
fn test_hook_lock() -> &'static AsyncMutex<()> {
5663
static LOCK: OnceLock<AsyncMutex<()>> = OnceLock::new();
5764
LOCK.get_or_init(|| AsyncMutex::new(()))
@@ -254,6 +261,7 @@ mod moved_tests {
254261
)),
255262
protocol_metadata: Arc::new(tokio::sync::Mutex::new(None)),
256263
shutting_down: AtomicBool::new(false),
264+
last_ping_ts: std::sync::atomic::AtomicI64::new(now_timestamp_ms()),
257265
stopped_tx: tokio::sync::watch::channel(true).0,
258266
});
259267

0 commit comments

Comments
 (0)