fix(query): preserve structured backend errors
This commit is contained in:
1 parent
2e9dcdc26b
commit
bcafc4a474
58 files changed
+4182
-554
No files matched your search
@@ -472,6 +472,7 @@ fn user_shell_node_candidate() -> Option<NodeRuntimeCandidate> {
|
||||
Some(NodeRuntimeCandidate { node_path })
|
||||
}
|
||||
|
||||
#[cfg(not(windows))]
|
||||
fn prefixed_output_path(output: &str, prefix: &str) -> Option<PathBuf> {
|
||||
output
|
||||
.lines()
|
||||
@@ -834,7 +835,7 @@ fn path_string(path: &Path) -> String {
|
||||
pub(crate) fn locate_command(command: &str) -> Option<String> {
|
||||
#[cfg(windows)]
|
||||
{
|
||||
return locate_windows_command(command);
|
||||
locate_windows_command(command)
|
||||
}
|
||||
#[cfg(not(windows))]
|
||||
{
|
||||
@@ -909,7 +910,7 @@ fn command_output(command: &str, args: &[&str]) -> Result<CommandOutput, String>
|
||||
|
||||
#[cfg(windows)]
|
||||
{
|
||||
return run_windows_command_candidates(command, args).or(direct);
|
||||
run_windows_command_candidates(command, args).or(direct)
|
||||
}
|
||||
|
||||
#[cfg(not(windows))]
|
||||
@@ -986,7 +987,7 @@ fn windows_common_command_dirs() -> Vec<std::path::PathBuf> {
|
||||
#[cfg(windows)]
|
||||
fn run_command_through_user_shell(command: &str, args: &[&str]) -> Result<CommandOutput, String> {
|
||||
let script = windows_command_script(command, args);
|
||||
let mut output = run_command("powershell.exe", &["-NoProfile", "-ExecutionPolicy", "Bypass", "-Command", &script])?;
|
||||
let mut output = run_command("powershell.exe", ["-NoProfile", "-ExecutionPolicy", "Bypass", "-Command", &script])?;
|
||||
output.stdout = stdout_after_shell_marker(&output.stdout);
|
||||
Ok(output)
|
||||
}
|
||||
@@ -1080,13 +1081,12 @@ mod tests {
|
||||
#[cfg(windows)]
|
||||
use super::first_windows_command_path;
|
||||
#[cfg(not(windows))]
|
||||
use super::{bash_login_script, NodeRuntimeCandidate};
|
||||
use super::{bash_login_script, prefixed_output_path, NodeRuntimeCandidate};
|
||||
use super::{
|
||||
canonical_runtime_path, is_mcp_compatible_node_version, mcp_command_for_runtime, mcp_native_binary_path_for,
|
||||
mcp_package, normalized_reported_path, npm_cli_candidates, parse_minimum_node_version, parse_node_version,
|
||||
prefer_runtime, prefixed_output_path, require_managed_mcp_command, resolve_managed_mcp_command,
|
||||
stdout_after_shell_marker, NodeRuntime, NodeVersion, MCP_MIN_NODE_VERSION_REQUIREMENT, MCP_PACKAGE_NAME,
|
||||
SHELL_COMMAND_MARKER,
|
||||
prefer_runtime, require_managed_mcp_command, resolve_managed_mcp_command, stdout_after_shell_marker,
|
||||
NodeRuntime, NodeVersion, MCP_MIN_NODE_VERSION_REQUIREMENT, MCP_PACKAGE_NAME, SHELL_COMMAND_MARKER,
|
||||
};
|
||||
#[cfg(not(windows))]
|
||||
use super::{shell_command_script, shell_quote};
|
||||
@@ -1151,6 +1151,7 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(not(windows))]
|
||||
fn prefixed_output_path_ignores_empty_values() {
|
||||
let output = "node=/opt/node/bin/node\nmissing=\n";
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ use std::time::Instant;
|
||||
use tauri::{AppHandle, Emitter, State};
|
||||
|
||||
use crate::commands::connection::AppState;
|
||||
use dbx_core::backend_error::BackendError;
|
||||
use dbx_core::db;
|
||||
use dbx_core::models::connection::DatabaseType;
|
||||
use dbx_core::query_cancel::RunningTaskMetadata;
|
||||
@@ -18,7 +19,8 @@ struct ExecuteMultiProgress {
|
||||
success: bool,
|
||||
execution_time_ms: u128,
|
||||
affected_rows: u64,
|
||||
error: Option<String>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
error: Option<BackendError>,
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
@@ -38,7 +40,7 @@ pub async fn execute_query(
|
||||
client_session_id: Option<String>,
|
||||
timeout_secs: Option<u64>,
|
||||
execution_mode: Option<dbx_core::query::QueryExecutionMode>,
|
||||
) -> Result<db::QueryResult, String> {
|
||||
) -> Result<db::QueryResult, BackendError> {
|
||||
let execution_id = execution_id.filter(|id| !id.trim().is_empty());
|
||||
let registered_query = execution_id.as_ref().map(|id| {
|
||||
state.running_queries.register_task(
|
||||
@@ -48,7 +50,7 @@ pub async fn execute_query(
|
||||
});
|
||||
let cancel_token = registered_query.as_ref().map(|query| query.token());
|
||||
|
||||
dbx_core::query::execute_sql_statement_with_options(
|
||||
dbx_core::query::execute_sql_statement_with_options_typed(
|
||||
&state,
|
||||
&connection_id,
|
||||
&database,
|
||||
@@ -69,6 +71,7 @@ pub async fn execute_query(
|
||||
},
|
||||
)
|
||||
.await
|
||||
.map_err(dbx_core::query::QueryExecutionError::into_backend_error)
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
@@ -91,7 +94,7 @@ pub async fn execute_multi(
|
||||
use_transaction: Option<bool>,
|
||||
continue_on_error: Option<bool>,
|
||||
execution_mode: Option<dbx_core::query::QueryExecutionMode>,
|
||||
) -> Result<Vec<dbx_core::query::ExecuteMultiResult>, String> {
|
||||
) -> Result<Vec<dbx_core::query::ExecuteMultiResult>, BackendError> {
|
||||
let execution_id = execution_id.filter(|id| !id.trim().is_empty());
|
||||
let registered_query = execution_id.as_ref().map(|id| {
|
||||
state.running_queries.register_task(
|
||||
@@ -130,7 +133,7 @@ pub async fn execute_multi(
|
||||
schema
|
||||
);
|
||||
|
||||
let result = dbx_core::query::execute_multi_core_with_options_for_client_and_progress(
|
||||
let result = dbx_core::query::execute_multi_core_with_options_for_client_and_progress_typed(
|
||||
&state,
|
||||
&connection_id,
|
||||
&database,
|
||||
@@ -169,7 +172,7 @@ pub async fn execute_multi(
|
||||
error
|
||||
),
|
||||
}
|
||||
result
|
||||
result.map_err(dbx_core::query::QueryExecutionError::into_backend_error)
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
|
||||
Reference in new issue
Block a user