11// Copyright 2023-, Edge & Node, GraphOps, and Semiotic Labs.
22// SPDX-License-Identifier: Apache-2.0
33
4+ use std:: convert:: Infallible ;
5+
46use anyhow:: Error ;
57use axum:: {
68 response:: { IntoResponse , Response } ,
@@ -9,6 +11,8 @@ use axum::{
911use indexer_monitor:: EscrowAccountsError ;
1012use reqwest:: StatusCode ;
1113use serde:: Serialize ;
14+ use tap_core:: receipt:: ReceiptError ;
15+ use tap_core:: Error as TapError ;
1216use thegraph_core:: DeploymentId ;
1317use thiserror:: Error ;
1418
@@ -25,31 +29,37 @@ pub enum IndexerServiceError {
2529 SerializationError ( #[ from] serde_json:: Error ) ,
2630
2731 #[ error( "Issues with provided receipt: {0}" ) ]
28- ReceiptError ( #[ from] tap_core:: Error ) ,
29-
32+ TapCoreError ( #[ from] tap_core:: Error ) ,
3033 #[ error( "There was an error while accessing escrow account: {0}" ) ]
3134 EscrowAccount ( #[ from] EscrowAccountsError ) ,
3235}
3336
37+ impl StatusCodeExt for IndexerServiceError {
38+ fn status_code ( & self ) -> StatusCode {
39+ use IndexerServiceError as E ;
40+ match & self {
41+ E :: TapCoreError ( ref error) => match error {
42+ TapError :: SignatureError ( _)
43+ | TapError :: ReceiptError ( ReceiptError :: CheckFailure ( _) ) => StatusCode :: BAD_REQUEST ,
44+ _ => StatusCode :: INTERNAL_SERVER_ERROR ,
45+ } ,
46+ E :: EscrowAccount ( _) | E :: ReceiptNotFound => StatusCode :: PAYMENT_REQUIRED ,
47+ E :: DeploymentIdNotFound => StatusCode :: INTERNAL_SERVER_ERROR ,
48+ E :: AxumError ( _) | E :: SerializationError ( _) => StatusCode :: BAD_GATEWAY ,
49+ }
50+ }
51+ }
52+
3453impl IntoResponse for IndexerServiceError {
3554 fn into_response ( self ) -> Response {
36- use IndexerServiceError :: * ;
37-
3855 #[ derive( Serialize ) ]
3956 struct ErrorResponse {
4057 message : String ,
4158 }
4259
43- let status = match self {
44- ReceiptError ( _) | EscrowAccount ( _) => StatusCode :: BAD_REQUEST ,
45- ReceiptNotFound => StatusCode :: PAYMENT_REQUIRED ,
46- DeploymentIdNotFound => StatusCode :: INTERNAL_SERVER_ERROR ,
47- AxumError ( _) => StatusCode :: INTERNAL_SERVER_ERROR ,
48- SerializationError ( _) => StatusCode :: BAD_REQUEST ,
49- } ;
5060 tracing:: error!( %self , "An IndexerServiceError occoured." ) ;
5161 (
52- status ,
62+ self . status_code ( ) ,
5363 Json ( ErrorResponse {
5464 message : self . to_string ( ) ,
5565 } ) ,
@@ -72,22 +82,50 @@ pub enum SubgraphServiceError {
7282 QueryForwardingError ( reqwest:: Error ) ,
7383}
7484
75- impl From < & SubgraphServiceError > for StatusCode {
76- fn from ( err : & SubgraphServiceError ) -> Self {
85+ impl StatusCodeExt for SubgraphServiceError {
86+ fn status_code ( & self ) -> StatusCode {
7787 use SubgraphServiceError :: * ;
78- match err {
79- InvalidStatusQuery ( _) => StatusCode :: BAD_REQUEST ,
80- UnsupportedStatusQueryFields ( _) => StatusCode :: BAD_REQUEST ,
81- StatusQueryError ( _) => StatusCode :: INTERNAL_SERVER_ERROR ,
82- InvalidDeployment ( _) => StatusCode :: BAD_REQUEST ,
83- QueryForwardingError ( _) => StatusCode :: INTERNAL_SERVER_ERROR ,
88+ match self {
89+ InvalidStatusQuery ( _) | UnsupportedStatusQueryFields ( _) => StatusCode :: BAD_REQUEST ,
90+ InvalidDeployment ( _) => StatusCode :: INTERNAL_SERVER_ERROR ,
91+ StatusQueryError ( _) => StatusCode :: BAD_GATEWAY ,
92+ QueryForwardingError ( _) => StatusCode :: SERVICE_UNAVAILABLE ,
8493 }
8594 }
8695}
8796
8897// Tell axum how to convert `SubgraphServiceError` into a response.
8998impl IntoResponse for SubgraphServiceError {
9099 fn into_response ( self ) -> Response {
91- ( StatusCode :: from ( & self ) , self . to_string ( ) ) . into_response ( )
100+ ( self . status_code ( ) , self . to_string ( ) ) . into_response ( )
101+ }
102+ }
103+
104+ pub trait StatusCodeExt {
105+ fn status_code ( & self ) -> StatusCode ;
106+ }
107+
108+ impl < T > StatusCodeExt for Response < T > {
109+ fn status_code ( & self ) -> StatusCode {
110+ self . status ( )
111+ }
112+ }
113+
114+ impl < T , E > StatusCodeExt for Result < T , E >
115+ where
116+ T : StatusCodeExt ,
117+ E : StatusCodeExt ,
118+ {
119+ fn status_code ( & self ) -> StatusCode {
120+ match self {
121+ Ok ( t) => t. status_code ( ) ,
122+ Err ( e) => e. status_code ( ) ,
123+ }
124+ }
125+ }
126+
127+ impl StatusCodeExt for Infallible {
128+ fn status_code ( & self ) -> StatusCode {
129+ unreachable ! ( )
92130 }
93131}
0 commit comments