# Docker Error Context Improvement - Demonstration ## Issue #266: Improved Error Context in Docker Sandbox Service ### Problem Original error handling pattern lost valuable context: ```typescript catch (error) { this.logger.error(`Failed to X: ${error.message}`); throw new Error(`Failed to X`); // ← Lost original error details! } ``` **What was lost:** - Original stack trace - Docker-specific error codes - Dockerode error details - Root cause information ### Solution Enhanced error handling preserves original error while adding context: ```typescript catch (error) { const enhancedError = error instanceof Error ? error : new Error(String(error)); enhancedError.message = `Failed to X: ${enhancedError.message}`; this.logger.error(enhancedError.message, enhancedError); throw enhancedError; // ← Preserves original error with enhanced message! } ``` **What's preserved:** - ✅ Original stack trace - ✅ Original error type (maintains instanceof checks) - ✅ Docker error codes and properties - ✅ Complete error chain for debugging - ✅ Added contextual information (agentId, containerId, operation) ### Methods Updated | Method | Line | Error Context Added | | ---------------------- | ------- | ----------------------------------------------- | | `createContainer()` | 126-133 | Agent ID + original Docker error | | `startContainer()` | 144-151 | Container ID + original Docker error | | `stopContainer()` | 165-172 | Container ID + original Docker error | | `removeContainer()` | 183-190 | Container ID + original Docker error | | `getContainerStatus()` | 201-208 | Container ID + original Docker error | | `cleanup()` | 226-233 | Container ID + cleanup context + original error | ### Example Error Improvements #### Before (Lost Context) ``` Error: Failed to create container for agent agent-123 at DockerSandboxService.createContainer (/src/spawner/docker-sandbox.service.ts:130) ... (new stack trace, original lost) ``` #### After (Preserved Context) ``` Error: Failed to create container for agent agent-123: connect ECONNREFUSED /var/run/docker.sock at Socket. (/node_modules/dockerode/lib/docker.js:85:15) at Socket.emit (node:events:514:28) ... (original Docker error stack trace preserved) at DockerSandboxService.createContainer (/src/spawner/docker-sandbox.service.ts:132) ``` ### Benefits 1. **Better Debugging**: Full stack trace shows where Docker error originated 2. **Root Cause Analysis**: Original error codes help identify exact issue 3. **Error Monitoring**: Logging systems can capture complete error context 4. **Diagnostics**: Docker-specific errors (ECONNREFUSED, ENOENT, etc.) preserved 5. **Backwards Compatible**: Tests still pass, error messages include required context ### Verification ```bash # TypeScript compilation pnpm --filter @mosaic/orchestrator typecheck # ✅ Result: 0 errors # Test suite pnpm --filter @mosaic/orchestrator test # ✅ Result: 395/395 tests passed # All error tests verify: # - Error message includes context (agentId/containerId) # - Error is thrown (not swallowed) # - Original error information preserved ``` ### Testing Error Context Example test demonstrating preserved context: ```typescript it("should preserve Docker error details", async () => { const dockerError = new Error("connect ECONNREFUSED /var/run/docker.sock"); (dockerError as any).code = "ECONNREFUSED"; (dockerError as any).errno = -111; mockDocker.createContainer.mockRejectedValue(dockerError); try { await service.createContainer("agent-123", "task-456", "/workspace"); fail("Should have thrown error"); } catch (error) { // Enhanced message includes context expect(error.message).toContain("Failed to create container for agent agent-123"); expect(error.message).toContain("ECONNREFUSED"); // Original error properties preserved expect(error.code).toBe("ECONNREFUSED"); expect(error.errno).toBe(-111); // Stack trace preserved expect(error.stack).toContain("dockerode"); } }); ``` ### Impact This improvement applies to all Docker operations: - Container creation errors now show why image pull failed - Start errors show why container couldn't start - Stop errors show why graceful shutdown failed - Remove errors show why cleanup couldn't complete - Status errors show why inspection failed **Every error now provides complete diagnostic information for troubleshooting.**