Replace res.json() with res.text() + fallback JSON parse so that
non-JSON error bodies (e.g. HTTP 502 with empty body) no longer
produce the unclear 'error decoding response body' message.
Also add 502/503/504 to classify_error for proper category prefixes.
- Use synchronous pool removal in desktop disconnect_db to prevent
race condition when user quickly disconnects and reconnects
- Rename recordMetadataLoadError to recordConnectionLostError and
export it for cross-store reuse
- Sync query execution errors back to connection state via
recordConnectionLostError in queryStore catch blocks
- Add backend check_connection_health method (dbx-core) with Tauri
command and web route for proactive pool verification
- Add frontend checkConnectionHealth API (tauri.ts/http.ts/api.ts)
- Enhance ensureConnected to verify backend pool health before
assuming connection is valid, auto-reconnect if stale
Root cause:
- AgentDriverClient::kill() is called during Drop to clean up child processes
- Old implementation called child.wait() and ignored errors with let _
- When wait() fails (e.g., process already killed by signal), child is not reaped and becomes zombie
Fix:
- Use try_wait() non-blocking polling, up to 100ms timeout
- Avoid long blocking in Drop during async cleanup
- Still perform final blocking wait() as fallback after timeout
- Log all wait errors for debugging
Impact:
- All JDBC agents (Oracle/DB2/DM8/XuguDB etc.)
- Prevents zombie process accumulation during long-running sessions
Disable COM_RESET_CONNECTION for single-connection session pools
(max_connections == 1) so that MySQL session state such as TEMPORARY
TABLEs is not cleared when a connection is returned to the pool.
Closes#1509