alibaba / alibaba/ROCK

fix(sdk): nohup mode always returns exit_code=0 regardless of command result

Open
#685 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
Python
Stars
485
Forks
81
Avg merge
16h 12m
Merged PRs (30d)
8

Description

## Problem

`Sandbox.arun()` in nohup mode always returns `exit_code=0` when the process completes within `wait_timeout`, regardless of whether the command actually succeeded or failed.

```python
result = await sandbox.arun(cmd="nonexistent_command_xyz", session="s", mode="nohup")
# Current: result.exit_code == 0 ← wrong, command not found should be 127
```

This makes it impossible for callers to distinguish between a successful command and a failed one via `exit_code`.

## Root Cause

`handle_nohup_output` hardcodes `exit_code=0` when `success=True` (process completed within timeout), with no mechanism to capture the actual exit status of the background command.

## Proposed Fix

Add a `capture_exit_code: bool = False` parameter to `arun()`. When `True`, the nohup command is wrapped in a subshell that writes the exit code to a `.rc` file:

```bash
# before
nohup {cmd} < /dev/null > {out} 2>&1 & echo PIDSTART${!}PIDEND;disown

# after (capture_exit_code=True)
( nohup {cmd} < /dev/null > {out} 2>&1; echo $? > {rc} ) & echo PIDSTART${!}PIDEND;disown
```

After the process completes, the `.rc` file is read to obtain the actual exit code.

The flag defaults to `False` for full backward compatibility.

## Acceptance Criteria

- `arun(cmd="nonexistent_command", mode="nohup", capture_exit_code=True)` → `exit_code=127`
- `arun(cmd="exit 42", mode="nohup", capture_exit_code=True)` → `exit_code=42`
- `arun(cmd="echo hello", mode="nohup", capture_exit_code=True)` → `exit_code=0`
- Default `capture_exit_code=False` behavior unchanged
- Timeout still returns `exit_code=1`

Contributor guide

No contributing guide indexed for this repository

Research direction

Start with Sandbox.arun() and handle_nohup_output, then trace the nohup command construction and output handling. Add coverage for captured exit codes 127, 42, and 0, while verifying the default behavior and timeout exit_code=1 remain unchanged.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
backend
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
65/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.