1- use axum:: response:: { IntoResponse , Response } ;
1+ use axum:: { Json , response:: IntoResponse , response:: Response } ;
2+ use core_executor:: error:: ExecutionError ;
3+ use core_metastore:: error:: MetastoreError ;
24use http:: StatusCode ;
35use serde:: { Deserialize , Serialize } ;
46use snafu:: prelude:: * ;
@@ -7,13 +9,9 @@ use snafu::prelude::*;
79#[ snafu( visibility( pub ) ) ]
810pub enum UIError {
911 #[ snafu( transparent) ]
10- Execution {
11- source : core_executor:: error:: ExecutionError ,
12- } ,
12+ Execution { source : ExecutionError } ,
1313 #[ snafu( transparent) ]
14- Metastore {
15- source : core_metastore:: error:: MetastoreError ,
16- } ,
14+ Metastore { source : MetastoreError } ,
1715}
1816pub type UIResult < T > = Result < T , UIError > ;
1917
@@ -43,8 +41,130 @@ pub struct ErrorResponse {
4341impl IntoResponse for UIError {
4442 fn into_response ( self ) -> Response < axum:: body:: Body > {
4543 match self {
46- Self :: Execution { source } => source . into_response ( ) ,
47- Self :: Metastore { source } => source . into_response ( ) ,
44+ Self :: Execution { source } => exec_error_into_response ( source ) ,
45+ Self :: Metastore { source } => metastore_error_into_response ( source ) ,
4846 }
4947 }
5048}
49+
50+ fn metastore_error_into_response ( error : MetastoreError ) -> axum:: response:: Response {
51+ let message = error. to_string ( ) ;
52+ let code = match error {
53+ MetastoreError :: TableDataExists { .. }
54+ | MetastoreError :: ObjectAlreadyExists { .. }
55+ | MetastoreError :: VolumeAlreadyExists { .. }
56+ | MetastoreError :: DatabaseAlreadyExists { .. }
57+ | MetastoreError :: SchemaAlreadyExists { .. }
58+ | MetastoreError :: TableAlreadyExists { .. }
59+ | MetastoreError :: VolumeInUse { .. } => http:: StatusCode :: CONFLICT ,
60+ MetastoreError :: TableRequirementFailed { .. } => http:: StatusCode :: UNPROCESSABLE_ENTITY ,
61+ MetastoreError :: VolumeValidationFailed { .. }
62+ | MetastoreError :: VolumeMissingCredentials
63+ | MetastoreError :: Validation { .. } => http:: StatusCode :: BAD_REQUEST ,
64+ MetastoreError :: CloudProviderNotImplemented { .. } => http:: StatusCode :: PRECONDITION_FAILED ,
65+ MetastoreError :: VolumeNotFound { .. }
66+ | MetastoreError :: DatabaseNotFound { .. }
67+ | MetastoreError :: SchemaNotFound { .. }
68+ | MetastoreError :: TableNotFound { .. }
69+ | MetastoreError :: ObjectNotFound => http:: StatusCode :: NOT_FOUND ,
70+ MetastoreError :: ObjectStore { .. }
71+ | MetastoreError :: ObjectStorePath { .. }
72+ | MetastoreError :: CreateDirectory { .. }
73+ | MetastoreError :: SlateDB { .. }
74+ | MetastoreError :: UtilSlateDB { .. }
75+ | MetastoreError :: Iceberg { .. }
76+ | MetastoreError :: Serde { .. }
77+ | MetastoreError :: TableMetadataBuilder { .. }
78+ | MetastoreError :: TableObjectStoreNotFound { .. }
79+ | MetastoreError :: UrlParse { .. } => http:: StatusCode :: INTERNAL_SERVER_ERROR ,
80+ } ;
81+
82+ let error = ErrorResponse {
83+ message,
84+ status_code : code. as_u16 ( ) ,
85+ } ;
86+ ( code, Json ( error) ) . into_response ( )
87+ }
88+
89+ fn exec_error_into_response ( error : ExecutionError ) -> axum:: response:: Response {
90+ let status_code = match & error {
91+ ExecutionError :: RegisterUDF { .. }
92+ | ExecutionError :: RegisterUDAF { .. }
93+ | ExecutionError :: InvalidTableIdentifier { .. }
94+ | ExecutionError :: InvalidSchemaIdentifier { .. }
95+ | ExecutionError :: InvalidFilePath { .. }
96+ | ExecutionError :: InvalidBucketIdentifier { .. }
97+ | ExecutionError :: TableProviderNotFound { .. }
98+ | ExecutionError :: MissingDataFusionSession { .. }
99+ | ExecutionError :: Utf8 { .. }
100+ | ExecutionError :: VolumeNotFound { .. }
101+ | ExecutionError :: ObjectStore { .. }
102+ | ExecutionError :: ObjectAlreadyExists { .. }
103+ | ExecutionError :: UnsupportedFileFormat { .. }
104+ | ExecutionError :: RefreshCatalogList { .. }
105+ | ExecutionError :: UrlParse { .. }
106+ | ExecutionError :: JobError { .. }
107+ | ExecutionError :: UploadFailed { .. } => http:: StatusCode :: BAD_REQUEST ,
108+ ExecutionError :: Arrow { .. }
109+ | ExecutionError :: S3Tables { .. }
110+ | ExecutionError :: Iceberg { .. }
111+ | ExecutionError :: CatalogListDowncast { .. }
112+ | ExecutionError :: CatalogDownCast { .. }
113+ | ExecutionError :: RegisterCatalog { .. } => http:: StatusCode :: INTERNAL_SERVER_ERROR ,
114+ ExecutionError :: DatabaseNotFound { .. }
115+ | ExecutionError :: TableNotFound { .. }
116+ | ExecutionError :: SchemaNotFound { .. }
117+ | ExecutionError :: CatalogNotFound { .. }
118+ | ExecutionError :: Metastore { .. }
119+ | ExecutionError :: DataFusion { .. }
120+ | ExecutionError :: DataFusionQuery { .. } => http:: StatusCode :: OK ,
121+ } ;
122+
123+ let message = match & error {
124+ ExecutionError :: DataFusion { source } => format ! ( "DataFusion error: {source}" ) ,
125+ ExecutionError :: DataFusionQuery { source, query } => {
126+ format ! ( "DataFusion error: {source}, query: {query}" )
127+ }
128+ ExecutionError :: InvalidTableIdentifier { ident } => {
129+ format ! ( "Invalid table identifier: {ident}" )
130+ }
131+ ExecutionError :: InvalidSchemaIdentifier { ident } => {
132+ format ! ( "Invalid schema identifier: {ident}" )
133+ }
134+ ExecutionError :: InvalidFilePath { path } => format ! ( "Invalid file path: {path}" ) ,
135+ ExecutionError :: InvalidBucketIdentifier { ident } => {
136+ format ! ( "Invalid bucket identifier: {ident}" )
137+ }
138+ ExecutionError :: Arrow { source } => format ! ( "Arrow error: {source}" ) ,
139+ ExecutionError :: TableProviderNotFound { table_name } => {
140+ format ! ( "No Table Provider found for table: {table_name}" )
141+ }
142+ ExecutionError :: MissingDataFusionSession { id } => {
143+ format ! ( "Missing DataFusion session for id: {id}" )
144+ }
145+ ExecutionError :: Utf8 { source } => format ! ( "Error encoding UTF8 string: {source}" ) ,
146+ ExecutionError :: Metastore { source } => format ! ( "Metastore error: {source}" ) ,
147+ ExecutionError :: DatabaseNotFound { db } => format ! ( "Database not found: {db}" ) ,
148+ ExecutionError :: TableNotFound { table } => format ! ( "Table not found: {table}" ) ,
149+ ExecutionError :: SchemaNotFound { schema } => format ! ( "Schema not found: {schema}" ) ,
150+ ExecutionError :: VolumeNotFound { volume } => format ! ( "Volume not found: {volume}" ) ,
151+ ExecutionError :: ObjectStore { source } => format ! ( "Object store error: {source}" ) ,
152+ ExecutionError :: ObjectAlreadyExists { type_name, name } => {
153+ format ! ( "Object of type {type_name} with name {name} already exists" )
154+ }
155+ ExecutionError :: UnsupportedFileFormat { format } => {
156+ format ! ( "Unsupported file format {format}" )
157+ }
158+ ExecutionError :: RefreshCatalogList { source } => {
159+ format ! ( "Refresh Catalog List error: {source}" )
160+ }
161+ _ => "Internal server error" . to_string ( ) ,
162+ } ;
163+
164+ // TODO: Is it correct?!
165+ let error = ErrorResponse {
166+ message,
167+ status_code : status_code. as_u16 ( ) ,
168+ } ;
169+ ( status_code, Json ( error) ) . into_response ( )
170+ }
0 commit comments