diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs index 26474a15..4e4ce79f 100644 --- a/src-tauri/src/lib.rs +++ b/src-tauri/src/lib.rs @@ -74,8 +74,8 @@ use yaak_plugin_runtime::events::{ }; use yaak_plugin_runtime::plugin_handle::PluginHandle; use yaak_sse::sse::ServerSentEvent; -use yaak_templates::{Parser, Tokens}; use yaak_templates::format::format_json; +use yaak_templates::{Parser, Tokens}; mod analytics; mod export_resources; @@ -174,7 +174,10 @@ async fn cmd_grpc_reflect( window: WebviewWindow, grpc_handle: State<'_, Mutex>, ) -> Result, String> { - let req = get_grpc_request(&window, request_id).await.map_err(|e| e.to_string())?; + let req = get_grpc_request(&window, request_id) + .await + .map_err(|e| e.to_string())? + .ok_or("Failed to find GRPC request")?; let uri = safe_uri(&req.url); @@ -201,7 +204,10 @@ async fn cmd_grpc_go( Some(id) => Some(get_environment(&window, id).await.map_err(|e| e.to_string())?), None => None, }; - let req = get_grpc_request(&window, request_id).await.map_err(|e| e.to_string())?; + let req = get_grpc_request(&window, request_id) + .await + .map_err(|e| e.to_string())? + .ok_or("Failed to find GRPC request")?; let workspace = get_workspace(&window, &req.workspace_id).await.map_err(|e| e.to_string())?; let req = render_grpc_request( &req, @@ -1436,12 +1442,12 @@ async fn cmd_get_folder(id: &str, w: WebviewWindow) -> Result { } #[tauri::command] -async fn cmd_get_grpc_request(id: &str, w: WebviewWindow) -> Result { +async fn cmd_get_grpc_request(id: &str, w: WebviewWindow) -> Result, String> { get_grpc_request(&w, id).await.map_err(|e| e.to_string()) } #[tauri::command] -async fn cmd_get_http_request(id: &str, w: WebviewWindow) -> Result { +async fn cmd_get_http_request(id: &str, w: WebviewWindow) -> Result, String> { get_http_request(&w, id).await.map_err(|e| e.to_string()) } @@ -2079,7 +2085,7 @@ async fn handle_plugin_event( })) } InternalEventPayload::GetHttpRequestByIdRequest(req) => { - let http_request = get_http_request(app_handle, req.id.as_str()).await.ok(); + let http_request = get_http_request(app_handle, req.id.as_str()).await.unwrap(); Some(InternalEventPayload::GetHttpRequestByIdResponse(GetHttpRequestByIdResponse { http_request, })) diff --git a/src-tauri/yaak_models/src/error.rs b/src-tauri/yaak_models/src/error.rs index 9a30eb93..9f0fb0ca 100644 --- a/src-tauri/yaak_models/src/error.rs +++ b/src-tauri/yaak_models/src/error.rs @@ -6,8 +6,10 @@ pub enum Error { SqlError(#[from] rusqlite::Error), #[error("JSON error: {0}")] JsonError(#[from] serde_json::Error), + #[error("Model not found {0}")] + ModelNotFound(String), #[error("unknown error")] Unknown, } -pub type Result = std::result::Result; \ No newline at end of file +pub type Result = std::result::Result; diff --git a/src-tauri/yaak_models/src/queries.rs b/src-tauri/yaak_models/src/queries.rs index e98e3a58..af76682e 100644 --- a/src-tauri/yaak_models/src/queries.rs +++ b/src-tauri/yaak_models/src/queries.rs @@ -1,5 +1,6 @@ use std::fs; +use crate::error::Error::ModelNotFound; use crate::error::Result; use crate::models::{ CookieJar, CookieJarIden, Environment, EnvironmentIden, Folder, FolderIden, GrpcConnection, @@ -299,7 +300,12 @@ pub async fn duplicate_grpc_request( window: &WebviewWindow, id: &str, ) -> Result { - let mut request = get_grpc_request(window, id).await?.clone(); + let mut request = match get_grpc_request(window, id).await? { + Some(r) => r, + None => { + return Err(ModelNotFound(id.to_string())); + } + }; request.id = "".to_string(); upsert_grpc_request(window, &request).await } @@ -308,7 +314,12 @@ pub async fn delete_grpc_request( window: &WebviewWindow, id: &str, ) -> Result { - let req = get_grpc_request(window, id).await?; + let req = match get_grpc_request(window, id).await? { + Some(r) => r, + None => { + return Err(ModelNotFound(id.to_string())); + } + }; let dbm = &*window.app_handle().state::(); let db = dbm.0.lock().await.get().unwrap(); @@ -393,7 +404,10 @@ pub async fn upsert_grpc_request( Ok(emit_upserted_model(window, m)) } -pub async fn get_grpc_request(mgr: &impl Manager, id: &str) -> Result { +pub async fn get_grpc_request( + mgr: &impl Manager, + id: &str, +) -> Result> { let dbm = &*mgr.state::(); let db = dbm.0.lock().await.get().unwrap(); @@ -403,7 +417,7 @@ pub async fn get_grpc_request(mgr: &impl Manager, id: &str) -> Re .cond_where(Expr::col(GrpcRequestIden::Id).eq(id)) .build_rusqlite(SqliteQueryBuilder); let mut stmt = db.prepare(sql.as_str())?; - Ok(stmt.query_row(&*params.as_params(), |row| row.try_into())?) + Ok(stmt.query_row(&*params.as_params(), |row| row.try_into()).optional()?) } pub async fn list_grpc_requests( @@ -1083,7 +1097,10 @@ pub async fn duplicate_http_request( window: &WebviewWindow, id: &str, ) -> Result { - let mut request = get_http_request(window, id).await?.clone(); + let mut request = match get_http_request(window, id).await? { + None => return Err(ModelNotFound(id.to_string())), + Some(r) => r, + }; request.id = "".to_string(); upsert_http_request(window, request).await } @@ -1181,7 +1198,10 @@ pub async fn list_http_requests( Ok(items.map(|v| v.unwrap()).collect()) } -pub async fn get_http_request(mgr: &impl Manager, id: &str) -> Result { +pub async fn get_http_request( + mgr: &impl Manager, + id: &str, +) -> Result> { let dbm = &*mgr.state::(); let db = dbm.0.lock().await.get().unwrap(); @@ -1191,14 +1211,17 @@ pub async fn get_http_request(mgr: &impl Manager, id: &str) -> Re .cond_where(Expr::col(HttpRequestIden::Id).eq(id)) .build_rusqlite(SqliteQueryBuilder); let mut stmt = db.prepare(sql.as_str())?; - Ok(stmt.query_row(&*params.as_params(), |row| row.try_into())?) + Ok(stmt.query_row(&*params.as_params(), |row| row.try_into()).optional()?) } pub async fn delete_http_request( window: &WebviewWindow, id: &str, ) -> Result { - let req = get_http_request(window, id).await?; + let req = match get_http_request(window, id).await? { + None => return Err(ModelNotFound(id.to_string())), + Some(r) => r, + }; // DB deletes will cascade but this will delete the files delete_all_http_responses_for_request(window, id).await?; @@ -1258,7 +1281,10 @@ pub async fn create_http_response( delete_http_response(window, response.id.as_str()).await?; } - let req = get_http_request(window, request_id).await?; + let req = match get_http_request(window, request_id).await? { + None => return Err(ModelNotFound(request_id.to_string())), + Some(r) => r, + }; let id = generate_model_id(ModelType::TypeHttpResponse); let dbm = &*window.app_handle().state::(); let db = dbm.0.lock().await.get().unwrap(); diff --git a/src-web/components/Sidebar.tsx b/src-web/components/Sidebar.tsx index 82b7da95..0f1af7ff 100644 --- a/src-web/components/Sidebar.tsx +++ b/src-web/components/Sidebar.tsx @@ -724,7 +724,7 @@ function SidebarItem({ switch (e.key) { case 'Enter': e.preventDefault(); - handleSubmitNameEdit(e.currentTarget); + await handleSubmitNameEdit(e.currentTarget); break; case 'Escape': e.preventDefault(); diff --git a/src-web/hooks/useSyncModelStores.ts b/src-web/hooks/useSyncModelStores.ts index 5ff952a8..5cbb0888 100644 --- a/src-web/hooks/useSyncModelStores.ts +++ b/src-web/hooks/useSyncModelStores.ts @@ -4,7 +4,7 @@ import type { AnyModel } from '@yaakapp-internal/models'; import { useSetAtom } from 'jotai/index'; import { extractKeyValue } from '../lib/keyValueStore'; import { modelsEq } from '../lib/model_util'; -import {useActiveWorkspace} from "./useActiveWorkspace"; +import { useActiveWorkspace } from './useActiveWorkspace'; import { cookieJarsAtom } from './useCookieJars'; import { environmentsAtom } from './useEnvironments'; import { foldersAtom } from './useFolders'; @@ -61,9 +61,7 @@ export function useSyncModelStores() { } // Mark these models as DESC instead of ASC - const pushToFront = (['http_response', 'grpc_connection'] as AnyModel['model'][]).includes( - model.model, - ); + const pushToFront = model.model === 'http_response' || model.model === 'grpc_connection'; if (shouldIgnoreModel(model, windowLabel)) return; @@ -106,7 +104,7 @@ export function useSyncModelStores() { const { model, windowLabel } = payload; if (shouldIgnoreModel(model, windowLabel)) return; - console.log('Delete model', payload.model); + console.log('Delete model', payload); if (model.model === 'workspace') { setWorkspaces(removeById(model));