| 376 | } |
| 377 | |
| 378 | func (r *NodeJSRuntime) Execute(ctx context.Context, code string, input map[string]any) (*ExecutionResult, error) { |
| 379 | start := time.Now() |
| 380 | |
| 381 | // 创建临时文件 |
| 382 | tmpFile, err := os.CreateTemp(r.config.WorkDir, "aster_*.js") |
| 383 | if err != nil { |
| 384 | return nil, fmt.Errorf("create temp file: %w", err) |
| 385 | } |
| 386 | defer func() { _ = os.Remove(tmpFile.Name()) }() |
| 387 | |
| 388 | // 包装代码 |
| 389 | wrappedCode := r.wrapCode(code, input) |
| 390 | if _, err := tmpFile.WriteString(wrappedCode); err != nil { |
| 391 | return nil, fmt.Errorf("write code: %w", err) |
| 392 | } |
| 393 | _ = tmpFile.Close() |
| 394 | |
| 395 | // 创建带超时的 context |
| 396 | execCtx, cancel := context.WithTimeout(ctx, r.config.Timeout) |
| 397 | defer cancel() |
| 398 | |
| 399 | // 执行 Node.js |
| 400 | cmd := exec.CommandContext(execCtx, r.nodePath, tmpFile.Name()) |
| 401 | cmd.Dir = r.config.WorkDir |
| 402 | |
| 403 | // 设置环境变量 |
| 404 | cmd.Env = os.Environ() |
| 405 | for k, v := range r.config.Env { |
| 406 | cmd.Env = append(cmd.Env, fmt.Sprintf("%s=%s", k, v)) |
| 407 | } |
| 408 | |
| 409 | var stdout, stderr bytes.Buffer |
| 410 | cmd.Stdout = &stdout |
| 411 | cmd.Stderr = &stderr |
| 412 | |
| 413 | err = cmd.Run() |
| 414 | duration := time.Since(start).Milliseconds() |
| 415 | |
| 416 | result := &ExecutionResult{ |
| 417 | Stdout: truncateOutput(stdout.String(), r.config.MaxOutput), |
| 418 | Stderr: truncateOutput(stderr.String(), r.config.MaxOutput), |
| 419 | Duration: duration, |
| 420 | } |
| 421 | |
| 422 | if err != nil { |
| 423 | if execCtx.Err() == context.DeadlineExceeded { |
| 424 | result.Error = "execution timeout" |
| 425 | result.ExitCode = -1 |
| 426 | } else if exitErr := (&exec.ExitError{}); errors.As(err, &exitErr) { |
| 427 | result.ExitCode = exitErr.ExitCode() |
| 428 | result.Error = stderr.String() |
| 429 | } else { |
| 430 | result.Error = err.Error() |
| 431 | result.ExitCode = -1 |
| 432 | } |
| 433 | return result, nil |
| 434 | } |
| 435 | |