entracte_lib/
renderer_log.rs1const MAX_FIELD_BYTES: usize = 8 * 1024;
12
13#[tauri::command]
14pub fn report_renderer_error(
15 message: String,
16 stack: Option<String>,
17 component_stack: Option<String>,
18) {
19 let message = redact_and_truncate(&message);
20 let stack = stack
21 .as_deref()
22 .map(redact_and_truncate)
23 .unwrap_or_else(|| "<none>".to_string());
24 let component_stack = component_stack
25 .as_deref()
26 .map(redact_and_truncate)
27 .unwrap_or_else(|| "<none>".to_string());
28 log::error!("renderer: {message} | stack={stack} | component_stack={component_stack}");
29}
30
31fn redact_and_truncate(input: &str) -> String {
37 let mut redacted = crate::license_redact::redact_license_shapes(input);
38 if redacted.len() > MAX_FIELD_BYTES {
39 let mut cut = MAX_FIELD_BYTES;
40 while cut > 0 && !redacted.is_char_boundary(cut) {
41 cut -= 1;
42 }
43 redacted.truncate(cut);
44 redacted.push_str("…[truncated]");
45 }
46 redacted
47}
48
49#[cfg(test)]
50mod tests {
51 use super::*;
52
53 #[test]
54 fn report_renderer_error_accepts_full_args() {
55 report_renderer_error(
56 "boom".to_string(),
57 Some("at foo (a.js:1)".to_string()),
58 Some("in <App/>".to_string()),
59 );
60 }
61
62 #[test]
63 fn report_renderer_error_accepts_missing_optionals() {
64 report_renderer_error("boom".to_string(), None, None);
65 }
66
67 #[test]
68 fn redact_and_truncate_caps_oversized_input() {
69 let huge = "x".repeat(MAX_FIELD_BYTES * 2);
70 let got = redact_and_truncate(&huge);
71 assert!(got.len() < MAX_FIELD_BYTES * 2);
72 assert!(got.ends_with("…[truncated]"));
73 }
74
75 #[test]
76 fn redact_and_truncate_masks_keys_before_truncating() {
77 let got = redact_and_truncate("oops ABCD-1111-2222-3333 in scope");
80 assert!(got.contains("[REDACTED-LS-KEY]"));
81 assert!(!got.contains("ABCD-1111-2222-3333"));
82 }
83
84 #[test]
85 fn redact_and_truncate_respects_char_boundary() {
86 let mut s = "a".repeat(MAX_FIELD_BYTES - 1);
88 s.push('日'); s.push_str("more");
90 let got = redact_and_truncate(&s);
91 assert!(got.ends_with("…[truncated]"));
92 let _ = std::str::from_utf8(got.as_bytes()).expect("must be valid utf-8");
94 }
95}