summaryrefslogtreecommitdiff
path: root/src/error.rs
diff options
context:
space:
mode:
authorOwen Jacobson <owen@grimoire.ca>2024-09-18 12:25:20 -0400
committerOwen Jacobson <owen@grimoire.ca>2024-09-18 12:25:20 -0400
commit526067fecf6bafec060d97162a16bc18cd74ad9b (patch)
tree0c3c0e24e3c9bc014f24798a5d6d2fbd4c8f558d /src/error.rs
parent9fb4d3e561786f01352cbd14894d994ea537b5ec (diff)
Log internal errors (and make it possible to track them down).
Diffstat (limited to 'src/error.rs')
-rw-r--r--src/error.rs43
1 files changed, 35 insertions, 8 deletions
diff --git a/src/error.rs b/src/error.rs
index 21caeda..2a6555f 100644
--- a/src/error.rs
+++ b/src/error.rs
@@ -1,10 +1,12 @@
-use std::error;
+use std::{error, fmt};
use axum::{
http::StatusCode,
response::{IntoResponse, Response},
};
+use crate::id::Id as BaseId;
+
// I'm making an effort to avoid `anyhow` here, as that crate is _enormously_
// complex (though very usable). We don't need to be overly careful about
// allocations on errors in this app, so this is fine for most "general
@@ -13,22 +15,47 @@ type BoxedError = Box<dyn error::Error + Send + Sync>;
// Returns a 500 Internal Server Error to the client. Meant to be used via the
// `?` operator; _does not_ return the originating error to the client.
-#[derive(Debug)]
-pub struct InternalError;
+pub struct InternalError(Id, BoxedError);
impl<E> From<E> for InternalError
where
E: Into<BoxedError>,
{
- fn from(_: E) -> Self {
- // At some point it may be useful for this to record the originating
- // error so that it can be logged… -oj
- Self
+ fn from(error: E) -> Self {
+ let id = Id::generate();
+ Self(id, error.into())
}
}
impl IntoResponse for InternalError {
fn into_response(self) -> Response {
- (StatusCode::INTERNAL_SERVER_ERROR, "internal server error").into_response()
+ let Self(id, error) = self;
+ eprintln!("hi: [{id}] {error}");
+ (
+ StatusCode::INTERNAL_SERVER_ERROR,
+ format!("internal server error\nerror id: {}", id),
+ )
+ .into_response()
+ }
+}
+
+/// Transient identifier for an InternalError. Prefixed with `E`.
+pub struct Id(BaseId);
+
+impl From<BaseId> for Id {
+ fn from(id: BaseId) -> Self {
+ Self(id)
+ }
+}
+
+impl Id {
+ pub fn generate() -> Self {
+ BaseId::generate("E")
+ }
+}
+
+impl fmt::Display for Id {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ self.0.fmt(f)
}
}