-
-
Notifications
You must be signed in to change notification settings - Fork 331
Expand file tree
/
Copy patherror_handler.rs
More file actions
129 lines (114 loc) · 3.99 KB
/
error_handler.rs
File metadata and controls
129 lines (114 loc) · 3.99 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
//! Error handling for rapier.
//!
//! A number of checks are in place to catch inconsistencies as soon as they occur,
//! while it's best to make sure none of these errors occur, some may be recoverable
//! through removing the root cause (incorrect shape or position for example).
//!
//! Setting [`GLOBAL_ERROR_HANDLER`] can help you as the end user to react to those errors.
//!
//! This module is typically NOT used by library authors, to allow end user to customize their own error handler.
//!
//! Its default behaviour is to [`panic!`].
use std::sync::OnceLock;
use log::warn;
/// Possible errors to handle through [`default_error_handler`].
#[derive(Debug, PartialEq, Eq, Clone)]
pub enum Error {
/// Error detected during `SAPAxis` `batch_insert`.
SapAxisInsert(String),
/// Error detected when trying to access a point key.
PointKey(String),
}
/// A global error handler. This can be set at startup, as long as it is set before
/// any uses.
///
/// # Example
///
/// ```
/// use crate::error::{GLOBAL_ERROR_HANDLER, warn};
/// GLOBAL_ERROR_HANDLER.set(warn).expect("The error handler can only be set once, globally.");
/// ```
pub static GLOBAL_ERROR_HANDLER: OnceLock<Box<dyn Fn(Error) + Sync + Send>> = OnceLock::new();
/// The default error handler. This defaults to [`panic()`].
#[inline]
pub fn default_error_handler() -> &'static dyn Fn(Error) {
GLOBAL_ERROR_HANDLER.get_or_init(|| Box::new(panic))
}
/// Error handler that panics with the error.
#[track_caller]
#[inline(always)]
pub fn panic(error: Error) {
panic!("Encountered an error:\n{:?}", error);
}
/// Error handler that logs the error at the `warn` level.
#[track_caller]
#[inline]
pub fn warn(error: Error) {
warn!("Encountered an error:\n{:?}", error);
}
#[cfg(all(feature = "dim3", feature = "f32"))]
#[cfg(test)]
mod test {
use core::f32;
use na::{Isometry, Translation3};
use crate::error_handler::GLOBAL_ERROR_HANDLER;
use crate::prelude::*;
use std::sync::mpsc::{self, Receiver, Sender};
#[test]
fn error_handling() {
use log::error;
let mut colliders = ColliderSet::new();
let mut impulse_joints = ImpulseJointSet::new();
let mut multibody_joints = MultibodyJointSet::new();
let mut pipeline = PhysicsPipeline::new();
let mut bf = BroadPhaseMultiSap::new();
let mut nf = NarrowPhase::new();
let mut bodies = RigidBodySet::new();
let mut islands = IslandManager::new();
let rb = RigidBodyBuilder::fixed()
.position(Isometry::from_parts(
Translation3::new(f32::MIN, f32::MIN, f32::MIN),
Rotation::identity(),
))
.build();
let h1 = bodies.insert(rb.clone());
let co = ColliderBuilder::ball(10.0).build();
colliders.insert_with_parent(co.clone(), h1, &mut bodies);
let (tx, rx): (Sender<i32>, Receiver<i32>) = mpsc::channel();
// Set error handling
if GLOBAL_ERROR_HANDLER
.set(Box::new(move |error| {
println!("error: {:?}", error);
// TODO: add more context:
// - offending rigidbody ?
// - backtrace ?
assert!(tx.send(1).is_ok());
}))
.is_err()
{
error!("The error handler can only be set once, globally.");
}
pipeline.step(
&Vector::zeros(),
&IntegrationParameters::default(),
&mut islands,
&mut bf,
&mut nf,
&mut bodies,
&mut colliders,
&mut impulse_joints,
&mut multibody_joints,
&mut CCDSolver::new(),
None,
&(),
&(),
);
assert!(rx.try_recv() == Ok(1));
assert!(rx.try_recv().is_ok());
assert!(rx.try_recv().is_ok());
assert!(rx.try_recv().is_ok());
assert!(rx.try_recv().is_ok());
assert!(rx.try_recv().is_ok());
assert!(rx.try_recv().is_err());
}
}