I have this perl package:
package Mojo::Runner;
use Mojo::Base 'Mojo::EventEmitter';
use Mojo::IOLoop::Subprocess;
use Mojo::Promise;
use IPC::Run;
sub run_p {
my ($self, $command, $stdin) = @_;
my ($stdout, $stderr);
my $subprocess = Mojo::IOLoop::Subprocess->new;
return $subprocess->run_p(sub {
my ($stdin, $stdout, $stderr);
my $process = IPC::Run::run $command, \$stdin, \$stdout, \$stderr;
my $e = $?;
my $promise = Mojo::Promise->new;
return $promise->reject($stderr) if $e;
return $stdout
})
}
1
that is supposed to run some process with IPC::Run from within a Mojo::IOLoop::Subprocess so that I can I use it as follows:
use FindBin qw($Bin);
use lib "$Bin/./lib";
use Mojo::Runner;
use strict;
$\ = "\n"; $, = "\t";
my $r = Mojo::Runner->new;
my $subprocess = $r->run_p(["rclone", "lsl", "my_own:", sprintf "--drive-root-folder-id=%s", "some_id" ])
->then(sub {
print $_ =~ s/\n$//msr for @_
})
->catch(sub {
my $err = shift;
print "Subprocess error: $err";
});
$subprocess->ioloop->start unless $subprocess->ioloop->is_running;
Now, when I intentionally fail it, for example by using the wrong command syntax, I get an error:
Unhandled rejected promise: 2024/10/01 17:25:57 Failed to lsl: couldn't list directory: googleapi: Error 404: File not found: ., notFound
at /Users/simone/perl5/perlbrew/perls/perl-5.36.0/lib/site_perl/5.36.0/Mojo/IOLoop/Subprocess.pm line 55.
If the IPC::Run process returns ok, everything works fine.
Why the unhandled promise? what do I need to change?
That "Unhandled rejected promise" is the one you create with
return $promise->reject($stderr) if $e;
The error message is emitted just before the then()
-handler in your code is executed.
You could simply change that to
die $stderr if $e;
and your code should behave as you expect it to.
I think what happens is that you create that rejected promise in the child process, but there is no handler for a rejected promise in the code executed in the child and you cannot transfer a rejected promise via JSON serialization from the child to the parent (where your catch handler exists).