( req: E2BShellExecutionRequest )
| 293 | } |
| 294 | |
| 295 | export async function executeShellInE2B( |
| 296 | req: E2BShellExecutionRequest |
| 297 | ): Promise<E2BExecutionResult> { |
| 298 | const { code, envs, timeoutMs } = req |
| 299 | |
| 300 | const sandbox = await createE2BSandbox(req.sandboxKind ?? 'shell') |
| 301 | const sandboxId = sandbox.sandboxId |
| 302 | |
| 303 | try { |
| 304 | // Inside the try so a failed mount still kills the sandbox via the finally below. |
| 305 | await writeSandboxInputs(sandbox, req.sandboxFiles, { sandboxId, rootUser: true }) |
| 306 | |
| 307 | let result: { stdout: string; stderr: string; exitCode: number } |
| 308 | try { |
| 309 | result = await sandbox.commands.run(code, { |
| 310 | envs: { |
| 311 | ...envs, |
| 312 | PATH: '/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/root/.local/bin', |
| 313 | }, |
| 314 | timeoutMs, |
| 315 | user: 'root', |
| 316 | }) |
| 317 | } catch (cmdError: any) { |
| 318 | const stderr = cmdError?.stderr || cmdError?.message || String(cmdError) |
| 319 | const stdout = cmdError?.stdout || '' |
| 320 | const exitCode = cmdError?.exitCode ?? 1 |
| 321 | logger.error('E2B shell command error', { |
| 322 | sandboxId, |
| 323 | exitCode, |
| 324 | error: stderr.slice(0, 500), |
| 325 | }) |
| 326 | return { |
| 327 | result: null, |
| 328 | stdout: [stdout, stderr].filter(Boolean).join('\n'), |
| 329 | error: stderr || `Command failed with exit code ${exitCode}`, |
| 330 | sandboxId, |
| 331 | } |
| 332 | } |
| 333 | |
| 334 | const stdout = [result.stdout, result.stderr].filter(Boolean).join('\n') |
| 335 | |
| 336 | if (result.exitCode !== 0) { |
| 337 | const errorMessage = result.stderr || `Process exited with code ${result.exitCode}` |
| 338 | logger.error('E2B shell execution error', { |
| 339 | sandboxId, |
| 340 | exitCode: result.exitCode, |
| 341 | stderr: result.stderr?.slice(0, 500), |
| 342 | }) |
| 343 | return { |
| 344 | result: null, |
| 345 | stdout, |
| 346 | error: errorMessage, |
| 347 | sandboxId, |
| 348 | } |
| 349 | } |
| 350 | |
| 351 | let parsed: unknown = null |
| 352 | const prefix = '__SIM_RESULT__=' |
no test coverage detected