mirror of
https://github.com/storytold/artcraft.git
synced 2026-10-27 04:00:10 -04:00
Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
feaac186aa |
@@ -24,6 +24,10 @@ pub struct NotificationDetails {
|
||||
/// Whether this notification originated from an error.
|
||||
pub(crate) is_from_error: bool,
|
||||
|
||||
/// Extra side-channel messages, eg. if we know we're sending an error/exception,
|
||||
/// but want to include an additional message. (The "description" field is messy atm.)
|
||||
pub(crate) extra_message: Option<String>,
|
||||
|
||||
/// HTTP method associated with the event, if any.
|
||||
pub(crate) http_method: Option<String>,
|
||||
|
||||
@@ -90,25 +94,30 @@ impl NotificationDetails {
|
||||
sections.push(desc.clone());
|
||||
}
|
||||
|
||||
// 2. Error chain
|
||||
// 2. Extra message
|
||||
if let Some(message) = &self.extra_message {
|
||||
sections.push(message.clone());
|
||||
}
|
||||
|
||||
// 3. Error chain
|
||||
if let Some(error_section) = self.format_error_chain() {
|
||||
sections.push(error_section);
|
||||
}
|
||||
|
||||
// 3. Event time
|
||||
// 4. Event time
|
||||
sections.push(self.format_event_time());
|
||||
|
||||
// 4. HTTP context
|
||||
// 5. HTTP context
|
||||
if let Some(http_section) = self.format_http_context() {
|
||||
sections.push(http_section);
|
||||
}
|
||||
|
||||
// 5. Service tokens
|
||||
// 6. Service tokens
|
||||
if let Some(tokens_section) = self.format_service_tokens() {
|
||||
sections.push(tokens_section);
|
||||
}
|
||||
|
||||
// 6. Application/service identity and hostname
|
||||
// 7. Application/service identity and hostname
|
||||
if let Some(identity_section) = Self::format_app_identity(application_name, service_id, hostname) {
|
||||
sections.push(identity_section);
|
||||
}
|
||||
|
||||
@@ -14,6 +14,10 @@ pub struct NotificationDetailsBuilder {
|
||||
pub(crate) maybe_error: Option<Arc<dyn std::error::Error + Send + Sync + 'static>>,
|
||||
pub(crate) is_from_error: bool,
|
||||
|
||||
/// Extra side-channel messages, eg. if we know we're sending an error/exception,
|
||||
/// but want to include an additional message. (The "description" field is messy atm.)
|
||||
pub(crate) extra_message: Option<String>,
|
||||
|
||||
pub(crate) http_method: Option<String>,
|
||||
pub(crate) http_path: Option<String>,
|
||||
pub(crate) http_status_code: Option<u16>,
|
||||
@@ -41,6 +45,7 @@ impl NotificationDetailsBuilder {
|
||||
event_time: Utc::now(),
|
||||
maybe_error: None,
|
||||
is_from_error: false,
|
||||
extra_message: None,
|
||||
http_method: None,
|
||||
http_path: None,
|
||||
http_status_code: None,
|
||||
@@ -70,6 +75,7 @@ impl NotificationDetailsBuilder {
|
||||
event_time: Utc::now(),
|
||||
maybe_error: Some(error),
|
||||
is_from_error: true,
|
||||
extra_message: None,
|
||||
http_method: None,
|
||||
http_path: None,
|
||||
http_status_code: None,
|
||||
@@ -106,6 +112,11 @@ impl NotificationDetailsBuilder {
|
||||
self
|
||||
}
|
||||
|
||||
pub fn set_extra_message(mut self, extra_message: Option<String>) -> Self {
|
||||
self.extra_message = extra_message;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn set_http_method(mut self, http_method: Option<String>) -> Self {
|
||||
self.http_method = http_method;
|
||||
self
|
||||
@@ -176,6 +187,7 @@ impl NotificationDetailsBuilder {
|
||||
event_time: self.event_time,
|
||||
maybe_error: self.maybe_error,
|
||||
is_from_error: self.is_from_error,
|
||||
extra_message: self.extra_message,
|
||||
http_method: self.http_method,
|
||||
http_path: self.http_path,
|
||||
http_status_code: self.http_status_code,
|
||||
|
||||
+27
-1
@@ -50,6 +50,12 @@ pub enum AdvancedCommonWebError {
|
||||
/// Stored in `Arc` so the error alerting middleware can clone it for paging
|
||||
/// without consuming the original.
|
||||
UncaughtServerError(Arc<dyn std::error::Error + Send + Sync + 'static>),
|
||||
|
||||
/// Same as above, with a specified extra message string
|
||||
UncaughtServerErrorWithInternalMessage {
|
||||
internal_message: String,
|
||||
error: Arc<dyn std::error::Error + Send + Sync + 'static>
|
||||
}
|
||||
}
|
||||
|
||||
// =============== Public accessors ===============
|
||||
@@ -60,6 +66,13 @@ impl AdvancedCommonWebError {
|
||||
Self::UncaughtServerError(Arc::new(error))
|
||||
}
|
||||
|
||||
pub fn from_error_with_message(message: String, error: impl std::error::Error + Send + Sync + 'static) -> Self {
|
||||
Self::UncaughtServerErrorWithInternalMessage {
|
||||
internal_message: message,
|
||||
error: Arc::new(error)
|
||||
}
|
||||
}
|
||||
|
||||
/// Wrap an `anyhow::Error` as an `UncaughtServerError`.
|
||||
/// (`anyhow::Error` doesn't implement `std::error::Error`, so `from_error` can't accept it.)
|
||||
pub fn from_anyhow_error(error: anyhow::Error) -> Self {
|
||||
@@ -75,6 +88,7 @@ impl AdvancedCommonWebError {
|
||||
pub fn cause(&self) -> Option<&(dyn std::error::Error + Send + Sync + 'static)> {
|
||||
match self {
|
||||
Self::UncaughtServerError(err) => Some(err.as_ref()),
|
||||
Self::UncaughtServerErrorWithInternalMessage { error, .. } => Some(error.as_ref()),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
@@ -84,13 +98,18 @@ impl AdvancedCommonWebError {
|
||||
pub fn clone_cause_arc(&self) -> Option<Arc<dyn std::error::Error + Send + Sync + 'static>> {
|
||||
match self {
|
||||
Self::UncaughtServerError(err) => Some(Arc::clone(err)),
|
||||
Self::UncaughtServerErrorWithInternalMessage { error, .. } => Some(Arc::clone(error)),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Whether this is a server error (500).
|
||||
pub fn is_server_error(&self) -> bool {
|
||||
matches!(self, Self::UncaughtServerError(_))
|
||||
match self {
|
||||
Self::UncaughtServerError(_) => true,
|
||||
Self::UncaughtServerErrorWithInternalMessage { .. } => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -104,6 +123,9 @@ impl Display for AdvancedCommonWebError {
|
||||
Self::NotFound => write!(f, "Not found"),
|
||||
Self::PaymentRequired => write!(f, "Payment required"),
|
||||
Self::UncaughtServerError(err) => write!(f, "Server error: {}", err),
|
||||
Self::UncaughtServerErrorWithInternalMessage { internal_message, error } => {
|
||||
write!(f, "Server error: {}: {}", internal_message, error)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -116,6 +138,9 @@ impl std::fmt::Debug for AdvancedCommonWebError {
|
||||
Self::NotFound => write!(f, "NotFound"),
|
||||
Self::PaymentRequired => write!(f, "PaymentRequired"),
|
||||
Self::UncaughtServerError(err) => write!(f, "UncaughtServerError({:?})", err),
|
||||
Self::UncaughtServerErrorWithInternalMessage { internal_message, error } => {
|
||||
write!(f, "UncaughtServerErrorWithInternalMessage({:?}, {:?})", internal_message, error)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -139,6 +164,7 @@ impl ResponseError for AdvancedCommonWebError {
|
||||
Self::NotFound => StatusCode::NOT_FOUND,
|
||||
Self::PaymentRequired => StatusCode::PAYMENT_REQUIRED,
|
||||
Self::UncaughtServerError(_) => StatusCode::INTERNAL_SERVER_ERROR,
|
||||
Self::UncaughtServerErrorWithInternalMessage { .. } => StatusCode::INTERNAL_SERVER_ERROR,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+4
-1
@@ -114,7 +114,10 @@ pub async fn edit_character_handler(
|
||||
.await
|
||||
.map_err(|err| {
|
||||
error!("Error updating character on Kinovi: {:?}", err);
|
||||
AdvancedCommonWebError::from_error(err)
|
||||
AdvancedCommonWebError::from_error_with_message(
|
||||
"Error Updating Kinovi Character API".to_string(),
|
||||
err,
|
||||
)
|
||||
})?;
|
||||
|
||||
info!("Updated character {} on Kinovi (name='{}')", kinovi_id, final_name);
|
||||
|
||||
+7
@@ -50,6 +50,13 @@ pub(crate) fn check_advanced_common_web_error(
|
||||
.set_session_token(metadata.session_token.clone())
|
||||
.set_session_user_token(metadata.session_user_token.clone());
|
||||
|
||||
match error {
|
||||
AdvancedCommonWebError::UncaughtServerErrorWithInternalMessage { internal_message, error } => {
|
||||
builder = builder.set_extra_message(Some(internal_message.to_string()));
|
||||
}
|
||||
_ => {},
|
||||
}
|
||||
|
||||
let notification = builder.build();
|
||||
|
||||
if let Err(err) = pager.enqueue_page(notification) {
|
||||
|
||||
+1
-1
@@ -16,7 +16,7 @@ pub(crate) fn check_status_code_fallback(
|
||||
) {
|
||||
match status_code {
|
||||
500 => {
|
||||
let summary = format!("HTTP 500: {} {}", method, path);
|
||||
let summary = format!("[Legacy] HTTP 500: {} {}", method, path);
|
||||
let description = format!(
|
||||
"An untyped HTTP 500 response was returned (no typed error matched).\n\n\
|
||||
Endpoint: {} {}\n\
|
||||
|
||||
Reference in New Issue
Block a user