diff --git a/services/reports/src/http.rs b/services/reports/src/http.rs
--- a/services/reports/src/http.rs
+++ b/services/reports/src/http.rs
@@ -1,10 +1,15 @@
-use actix_web::{web, App, HttpResponse, HttpServer};
+use actix_web::error::{
+  ErrorBadRequest, ErrorInternalServerError, ErrorServiceUnavailable,
+  ErrorUnsupportedMediaType,
+};
+use actix_web::{web, App, HttpResponse, HttpServer, ResponseError};
 use anyhow::Result;
-use tracing::info;
+use http::StatusCode;
+use tracing::{debug, error, info, trace, warn};
 
 use crate::config::CONFIG;
 use crate::constants::REQUEST_BODY_JSON_SIZE_LIMIT;
-use crate::service::ReportsService;
+use crate::service::{ReportsService, ReportsServiceError};
 
 pub async fn run_http_server(service: ReportsService) -> Result<()> {
   use actix_web::middleware::{Logger, NormalizePath};
@@ -34,3 +39,61 @@
 
   Ok(())
 }
+
+fn handle_reports_service_error(err: &ReportsServiceError) -> actix_web::Error {
+  use aws_sdk_dynamodb::Error as DynamoDBError;
+  use comm_services_lib::database::Error as DBError;
+
+  trace!("Handling reports service error: {:?}", err);
+  match err {
+    ReportsServiceError::UnsupportedReportType => {
+      ErrorUnsupportedMediaType("unsupported report type")
+    }
+    ReportsServiceError::SerdeError(err) => {
+      error!("Serde error: {0:?} - {0}", err);
+      ErrorInternalServerError("internal error")
+    }
+    ReportsServiceError::ParseError(err) => {
+      debug!("Parse error: {0:?} - {0}", err);
+      ErrorBadRequest("invalid input format")
+    }
+    ReportsServiceError::BlobError(err) => {
+      error!("Blob Service error: {0:?} - {0}", err);
+      ErrorInternalServerError("internal error")
+    }
+    ReportsServiceError::DatabaseError(db_err) => match db_err {
+      // retriable errors
+      DBError::MaxRetriesExceeded
+      | DBError::AwsSdk(
+        DynamoDBError::InternalServerError(_)
+        | DynamoDBError::ProvisionedThroughputExceededException(_)
+        | DynamoDBError::RequestLimitExceeded(_),
+      ) => {
+        warn!("AWS transient error occurred");
+        ErrorServiceUnavailable("please retry")
+      }
+      err => {
+        error!("Unexpected database error: {0:?} - {0}", err);
+        ErrorInternalServerError("internal error")
+      }
+    },
+    #[allow(unreachable_patterns)]
+    err => {
+      error!("Received an unexpected error: {0:?} - {0}", err);
+      ErrorInternalServerError("server error")
+    }
+  }
+}
+
+/// This allow us to `await?` blob service calls in HTTP handlers
+impl ResponseError for ReportsServiceError {
+  fn error_response(&self) -> HttpResponse {
+    handle_reports_service_error(self).error_response()
+  }
+
+  fn status_code(&self) -> StatusCode {
+    handle_reports_service_error(self)
+      .as_response_error()
+      .status_code()
+  }
+}
diff --git a/services/reports/src/service.rs b/services/reports/src/service.rs
--- a/services/reports/src/service.rs
+++ b/services/reports/src/service.rs
@@ -1,8 +1,36 @@
 use actix_web::FromRequest;
-use comm_services_lib::{auth::UserIdentity, blob::client::BlobServiceClient};
+use comm_services_lib::{
+  auth::UserIdentity,
+  blob::client::{BlobServiceClient, BlobServiceError},
+  database,
+};
+use derive_more::{Display, Error, From};
 use std::future::{ready, Ready};
 
 use crate::database::client::DatabaseClient;
+
+#[derive(Debug, Display, Error, From)]
+pub enum ReportsServiceError {
+  DatabaseError(database::Error),
+  BlobError(BlobServiceError),
+  /// Error during parsing user input
+  /// Usually this indicates user error
+  #[from(ignore)]
+  ParseError(serde_json::Error),
+  /// Error during serializing/deserializing internal data
+  /// This is usually a service bug / data inconsistency
+  #[from(ignore)]
+  SerdeError(serde_json::Error),
+  /// Unsupported report type
+  /// Returned when trying to perform an operation on an incompatible report type
+  /// e.g. create a Redux Devtools import from a media mission report
+  UnsupportedReportType,
+  /// Unexpected error
+  Unexpected,
+}
+
+type ServiceResult<T> = Result<T, ReportsServiceError>;
+
 #[derive(Clone)]
 pub struct ReportsService {
   db: DatabaseClient,