You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在Mojo::IOLoop::Subprocess中使用IPC::Run时未处理拒绝Promise问题排查

问题原因

你在run_p方法的子进程回调中,错误地返回了一个rejected状态的Promise对象。Mojo::IOLoop::Subprocess->run_p的工作机制是:子进程执行完回调逻辑后,会将返回值传递给父进程的Promise并标记为resolve状态。因此这个内部的rejected Promise会被当作成功结果返回给外层Promise,而它本身没有被任何代码处理,最终触发了“Unhandled rejected promise”报错。

修改方案

不需要在子进程回调中创建新的Promise,直接通过抛出异常触发外层Promise的reject状态即可。修改后的Mojo::Runner代码如下:

package Mojo::Runner;

use Mojo::Base 'Mojo::EventEmitter';

use Mojo::IOLoop::Subprocess;
use IPC::Run;

sub run_p {
    my ($self, $command, $stdin) = @_;

    my $subprocess = Mojo::IOLoop::Subprocess->new;

    return $subprocess->run_p(sub {
               my ($out_stdout, $out_stderr);
               # 执行外部命令,传入stdin(如果有)
               my $process = IPC::Run::run $command, \$stdin, \$out_stdout, \$out_stderr;

               my $exit_status = $?;

               # 命令执行失败时抛出异常,由run_p捕获并reject外层Promise
               die $out_stderr if $exit_status;
               # 执行成功则返回stdout
               return $out_stdout;
           });
}

1;
说明
  • 移除了子进程内多余的Mojo::Promise实例创建,改用die抛出错误,Mojo::IOLoop::Subprocess会自动捕获子进程中的异常,将run_p返回的Promise标记为rejected。
  • 修正了子进程内变量名冲突问题(原代码重新声明了$stdin、$stdout、$stderr,覆盖了外部参数),确保传入的stdin能正确传递给外部命令。
  • 修改后,当命令执行失败时,外层的catch块会正确捕获错误信息并处理,不会再出现未处理Promise的报错。

内容的提问来源于stack exchange,提问作者simone

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 16:12:37