Skip to content

Commit

Permalink
execute_query now returns LumniError, add conversion to ApplicationEr…
Browse files Browse the repository at this point in the history
…ror, allowing to catch NotFound in filebrowser
  • Loading branch information
aprxi committed Aug 26, 2024
1 parent 250f26b commit 3a91afe
Show file tree
Hide file tree
Showing 5 changed files with 87 additions and 28 deletions.
9 changes: 9 additions & 0 deletions lumni-web/src/components/apps/form_submit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,15 @@ pub fn AppFormSubmit(app_uri: String) -> impl IntoView {
LumniError::Runtime(RuntimeError::Unexpected(e)) => {
log::error!("RuntimeError - Unexpected: {}", e);
}
LumniError::ParseError(e) => {
log::error!("ParseError: {}", e);
}
LumniError::InternalError(e) => {
log::error!("InternalError: {}", e);
}
LumniError::Resource(e) => {
log::error!("ResourceError: {}", e);
}
LumniError::Invoke(e, _) => {
log::error!("InvokeError: {}", e);
}
Expand Down
35 changes: 32 additions & 3 deletions lumni/src/apps/api/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ pub enum LumniError {
Invoke(ApplicationError, Option<String>),
Resource(ResourceError),
NotImplemented(String),
InternalError(String),
ParseError(String),
Message(String),
Any(String),
}
Expand Down Expand Up @@ -65,9 +67,11 @@ impl fmt::Display for LumniError {
LumniError::Runtime(runtime_err) => {
write!(f, "RuntimeError: {}", runtime_err)
}
LumniError::ParseError(s) => write!(f, "ParseError: {}", s),
LumniError::Application(app_err, Some(app_name)) => {
write!(f, "[{}]: {}", app_name, app_err)
}
LumniError::InternalError(s) => write!(f, "InternalError: {}", s),
LumniError::Invoke(app_err, Some(app_name)) => {
write!(f, "[{}]: {}", app_name, app_err)
}
Expand Down Expand Up @@ -98,14 +102,39 @@ impl fmt::Display for RequestError {
impl From<LumniError> for ApplicationError {
fn from(error: LumniError) -> Self {
match error {
LumniError::Application(app_error, None) => app_error,
_ => {
ApplicationError::Unexpected("Unhandled LumniError".to_string())
LumniError::Application(app_error, _) => app_error,
LumniError::Resource(ResourceError::NotFound(s)) => {
ApplicationError::NotFound(s)
}
LumniError::Request(RequestError::QueryInvalid(s)) => {
ApplicationError::InvalidInput(s)
}
LumniError::Runtime(RuntimeError::Unexpected(s)) => {
ApplicationError::Runtime(s)
}
LumniError::ParseError(s) => ApplicationError::InvalidInput(s),
LumniError::InternalError(s) => ApplicationError::InternalError(s),
LumniError::Invoke(s, _) => {
ApplicationError::Runtime(s.to_string())
}
LumniError::NotImplemented(s) => {
ApplicationError::NotImplemented(s)
}
LumniError::Message(s) | LumniError::Any(s) => {
ApplicationError::Unexpected(s)
}
}
}
}

impl fmt::Display for ResourceError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
ResourceError::NotFound(s) => write!(f, "NotFound: {}", s),
}
}
}

impl fmt::Display for RuntimeError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use std::time::Instant;

use async_trait::async_trait;
use crossterm::event::KeyCode;
use futures::TryFutureExt;
use lumni::{EnvironmentConfig, ObjectStoreHandler, Table, TableColumnValue};
use ratatui::layout::{Alignment, Constraint, Direction, Layout, Margin, Rect};
use ratatui::style::{Color, Modifier, Style};
Expand Down Expand Up @@ -46,18 +47,31 @@ impl FileListHandler {
Self { handler }
}

async fn list_files(
async fn handle_query(
&self,
path: String,
query: String,
) -> Result<Arc<Box<dyn Table + Send + Sync>>, ApplicationError> {
let query = format!("SELECT * FROM \"localfs://{}\" LIMIT 100", path);
let config = EnvironmentConfig::new(HashMap::new());
match self
let result = self
.handler
.execute_query(&query, &config, true, false, None, None)
.await
{
Ok(table) => Ok(Arc::new(table as Box<dyn Table + Send + Sync>)),
.map_err(ApplicationError::from)?;
Ok(Arc::new(result as Box<dyn Table + Send + Sync>))
}

async fn list_files(
&self,
path: String,
) -> Result<Arc<Box<dyn Table + Send + Sync>>, ApplicationError> {
let query = format!("SELECT * FROM \"localfs://{}\" LIMIT 100", path);
match self.handle_query(query).await {
Ok(table) => Ok(table),
Err(ApplicationError::NotFound(_)) => {
let query =
"SELECT * FROM \"localfs://.\" LIMIT 100".to_string();
self.handle_query(query).await
}
Err(e) => match e {
// TODO: update execute_query to return LumniError::ResourceError
//ResourceError::NotFound => Err(ApplicationError::NotFound(path)),
Expand Down Expand Up @@ -324,9 +338,7 @@ impl<'a> FileBrowserModal<'a> {
let result = handler
.execute_query(&query, &config, true, false, None, None)
.await
.map_err(|e| {
ApplicationError::InternalError(e.to_string())
});
.map_err(ApplicationError::from);

let directory_change_result = match result {
Ok(_) => Ok(new_path),
Expand Down
4 changes: 2 additions & 2 deletions lumni/src/base/connector.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::{EnvironmentConfig, InternalError, ObjectStoreHandler, Table};
use crate::{EnvironmentConfig, LumniError, ObjectStoreHandler, Table};

#[derive(Clone)]
pub struct LumniHandler {
Expand All @@ -19,7 +19,7 @@ impl LumniHandler {
query: String,
skip_hidden: bool,
recursive: bool,
) -> Result<Box<dyn Table>, InternalError> {
) -> Result<Box<dyn Table>, LumniError> {
let callback = None;
let result = self
.handler
Expand Down
37 changes: 23 additions & 14 deletions lumni/src/handlers/object_store.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,18 @@ use std::sync::Arc;

use async_trait::async_trait;
use log::debug;
use pkcs8::der::asn1::Int;
use sqlparser::ast::{Expr, Query, SelectItem, SetExpr, Statement};
use sqlparser::dialect::GenericDialect;
use sqlparser::parser::Parser;

use crate::api::error::{LumniError, ResourceError};
use crate::localfs::backend::LocalFsBucket;
use crate::s3::backend::S3Bucket;
use crate::table::object_store::table_from_list_bucket;
use crate::table::{FileObjectTable, Table, TableCallback};
use crate::{
BinaryCallbackWrapper, EnvironmentConfig, FileObjectFilter, IgnoreContents,
InternalError, LumniError, ObjectStoreTable, ParsedUri, UriScheme,
InternalError, ObjectStoreTable, ParsedUri, UriScheme,
};

#[derive(Debug, Clone)]
Expand Down Expand Up @@ -317,7 +317,7 @@ impl ObjectStoreHandler {
recursive: bool,
ignore_contents: Option<IgnoreContents>,
callback: Option<Arc<dyn TableCallback>>,
) -> Result<Box<dyn Table>, InternalError> {
) -> Result<Box<dyn Table>, LumniError> {
let dialect = GenericDialect {};
let parsed = Parser::parse_sql(&dialect, statement);

Expand All @@ -326,22 +326,31 @@ impl ObjectStoreHandler {
if let Some(Statement::Query(query)) =
statements.into_iter().next()
{
self.handle_select_statement(
&query,
config,
skip_hidden,
recursive,
ignore_contents,
callback,
)
.await
let result = self
.handle_select_statement(
&query,
config,
skip_hidden,
recursive,
ignore_contents,
callback,
)
.await;

match result {
Ok(table) => Ok(table),
Err(InternalError::NotFound(e)) => Err(
LumniError::Resource(ResourceError::NotFound(e)),
),
Err(e) => Err(LumniError::InternalError(e.to_string())),
}
} else {
Err(InternalError::InternalError(
Err(LumniError::NotImplemented(
"Unsupported query statement".to_string(),
))
}
}
Err(_e) => Err(InternalError::InternalError(
Err(_e) => Err(LumniError::ParseError(
"Failed to parse query statement".to_string(),
)),
}
Expand Down

0 comments on commit 3a91afe

Please sign in to comment.