Improve error handling

This commit is contained in:
Mihai Dinculescu
2022-10-24 19:45:28 +01:00
parent 7186d61467
commit f47a597557
4 changed files with 31 additions and 24 deletions

View File

@@ -8,6 +8,10 @@ file. This change log follows the conventions of
## Changed ## Changed
- `SimConnect::get_next_dispatch` will now return an error of type `SimConnectError::UnimplementedMessageType` instead of panicking on unrecognized notification types.
- `SimConnect::get_next_dispatch` will now return an error of type `SimConnectError::SimConnectException` instead of `Notification::Exception`.
- `SimConnectError::SimConnectUnrecognizedEvent` has been renamed to `SimConnectError::UnimplementedEventType`.
- `#[non_exhaustive]` has been added to the `SimConnectError` and `Notification` enums.
- The tracing information has been adjusted to be at the `info` and `debug` levels instead of `info`. - The tracing information has been adjusted to be at the `info` and `debug` levels instead of `info`.
## [v0.1.2] - 2022-10-22 ## [v0.1.2] - 2022-10-22

View File

@@ -2,6 +2,7 @@ use crate::{Airport, Event, SimConnectError, SimConnectObjectExt, Waypoint, NDB,
/// Notification received from SimConnect. /// Notification received from SimConnect.
#[derive(Debug)] #[derive(Debug)]
#[non_exhaustive]
pub enum Notification { pub enum Notification {
/// SimConnect open /// SimConnect open
Open, Open,
@@ -19,8 +20,6 @@ pub enum Notification {
VorList(Vec<VOR>), VorList(Vec<VOR>),
/// SimConnect quit /// SimConnect quit
Quit, Quit,
/// SimConnect exception
Exception(u32),
} }
/// Notification data object. /// Notification data object.

View File

@@ -2,13 +2,20 @@ use thiserror::Error;
/// SimConnect SDK error. /// SimConnect SDK error.
#[derive(Error, Debug)] #[derive(Error, Debug)]
#[non_exhaustive]
pub enum SimConnectError { pub enum SimConnectError {
/// SimConnect error. /// SimConnect error.
#[error("SimConnect error: {0}")] #[error("SimConnect error: {0}")]
SimConnectError(i32), SimConnectError(i32),
#[error("SimConnect unrecognized: {0}")] /// SimConnect error.
/// SimConnect unrecognized error. Occurs when an unimplemented event is received by the SDK. #[error("SimConnect exception: {0}")]
SimConnectUnrecognizedEvent(u32), SimConnectException(u32),
/// An unimplemented event type has been received by the SDK.
#[error("Unimplemented event in the SDK: {0}")]
UnimplementedEventType(u32),
/// An unimplemented message type has been received by the SDK.
#[error("Unimplemented notification in the SDK: {0}")]
UnimplementedMessageType(i32),
/// Object already registered with the client instance. /// Object already registered with the client instance.
#[error("Object `{0}` has already been registered")] #[error("Object `{0}` has already been registered")]
ObjectAlreadyRegistered(String), ObjectAlreadyRegistered(String),

View File

@@ -144,25 +144,24 @@ impl SimConnect {
let span = span!(Level::TRACE, "SimConnect::get_next_dispatch"); let span = span!(Level::TRACE, "SimConnect::get_next_dispatch");
let _enter = span.enter(); let _enter = span.enter();
let result = match recv_id { match recv_id {
bindings::SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_OPEN => { bindings::SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_OPEN => {
trace!("Received SIMCONNECT_RECV_OPEN"); trace!("Received SIMCONNECT_RECV_OPEN");
Some(Notification::Open) Ok(Some(Notification::Open))
} }
bindings::SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_QUIT => { bindings::SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_QUIT => {
trace!("Received SIMCONNECT_RECV_QUIT"); trace!("Received SIMCONNECT_RECV_QUIT");
Some(Notification::Quit) Ok(Some(Notification::Quit))
} }
bindings::SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_EVENT => { bindings::SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_EVENT => {
trace!("Received SIMCONNECT_RECV_EVENT"); trace!("Received SIMCONNECT_RECV_EVENT");
let event: &bindings::SIMCONNECT_RECV_EVENT = let event: &bindings::SIMCONNECT_RECV_EVENT =
unsafe { &*(data_buf as *const bindings::SIMCONNECT_RECV_EVENT) }; unsafe { &*(data_buf as *const bindings::SIMCONNECT_RECV_EVENT) };
let event = Event::try_from(event.uEventID).map_err(|_| { let event = Event::try_from(event.uEventID)
SimConnectError::SimConnectUnimplementedEvent(event.uEventID) .map_err(|_| SimConnectError::UnimplementedEventType(event.uEventID))?;
})?;
Some(Notification::Event(event)) Ok(Some(Notification::Event(event)))
} }
bindings::SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_SIMOBJECT_DATA => { bindings::SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_SIMOBJECT_DATA => {
trace!("Received SIMCONNECT_RECV_SIMOBJECT_DATA"); trace!("Received SIMCONNECT_RECV_SIMOBJECT_DATA");
@@ -179,9 +178,9 @@ impl SimConnect {
data_addr: std::ptr::addr_of!(event.dwData), data_addr: std::ptr::addr_of!(event.dwData),
}; };
Some(Notification::Object(data)) Ok(Some(Notification::Object(data)))
} }
_ => None, _ => Ok(None),
} }
} }
bindings::SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_AIRPORT_LIST => { bindings::SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_AIRPORT_LIST => {
@@ -204,7 +203,7 @@ impl SimConnect {
}) })
.collect::<Vec<_>>(); .collect::<Vec<_>>();
Some(Notification::AirportList(data)) Ok(Some(Notification::AirportList(data)))
} }
bindings::SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_WAYPOINT_LIST => { bindings::SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_WAYPOINT_LIST => {
trace!("Received SIMCONNECT_RECV_WAYPOINT_LIST"); trace!("Received SIMCONNECT_RECV_WAYPOINT_LIST");
@@ -227,7 +226,7 @@ impl SimConnect {
}) })
.collect::<Vec<_>>(); .collect::<Vec<_>>();
Some(Notification::WaypointList(data)) Ok(Some(Notification::WaypointList(data)))
} }
bindings::SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_NDB_LIST => { bindings::SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_NDB_LIST => {
trace!("Received SIMCONNECT_RECV_NDB_LIST"); trace!("Received SIMCONNECT_RECV_NDB_LIST");
@@ -251,7 +250,7 @@ impl SimConnect {
}) })
.collect::<Vec<_>>(); .collect::<Vec<_>>();
Some(Notification::NdbList(data)) Ok(Some(Notification::NdbList(data)))
} }
bindings::SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_VOR_LIST => { bindings::SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_VOR_LIST => {
trace!("Received SIMCONNECT_RECV_VOR_LIST"); trace!("Received SIMCONNECT_RECV_VOR_LIST");
@@ -321,7 +320,7 @@ impl SimConnect {
}) })
.collect::<Vec<_>>(); .collect::<Vec<_>>();
Some(Notification::VorList(data)) Ok(Some(Notification::VorList(data)))
} }
bindings::SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_EXCEPTION => { bindings::SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_EXCEPTION => {
let event: &bindings::SIMCONNECT_RECV_EXCEPTION = let event: &bindings::SIMCONNECT_RECV_EXCEPTION =
@@ -329,16 +328,14 @@ impl SimConnect {
warn!("Received {:?}", event); warn!("Received {:?}", event);
Some(Notification::Exception(event.dwException)) Err(SimConnectError::SimConnectException(event.dwException))
} }
bindings::SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_NULL => None, bindings::SIMCONNECT_RECV_ID_SIMCONNECT_RECV_ID_NULL => Ok(None),
id => { id => {
error!("Received unhandled notification ID: {}", id); error!("Received unhandled notification ID: {}", id);
panic!("Got unrecognized notification: {id}"); Err(SimConnectError::UnimplementedMessageType(id))
} }
}; }
Ok(result)
} }
} }