new Client/Router/Service arch
[scpubgit/Tak.git] / lib / Tak / EvalService.pm
1 package Tak::EvalService;
2
3 use Eval::WithLexicals;
4 use Data::Dumper::Concise;
5 use Capture::Tiny qw(capture);
6 use Moo;
7
8 with 'Tak::Role::Service';
9
10 has 'eval_withlexicals' => (is => 'lazy');
11
12 sub _build_eval_withlexicals {
13   Eval::WithLexicals->new
14 }
15
16 sub handle_eval {
17   my ($self, $perl) = @_;
18   unless ($perl) {
19     die [ mistake => eval_input => "No code supplied" ];
20   }
21   if (my $ref = ref($perl)) {
22     die [ mistake => eval_input => "Code was a ${ref} reference" ];
23   }
24   my ($ok, @ret);
25   my ($stdout, $stderr);
26   if (eval {
27     ($stdout, $stderr) = capture {
28       @ret = $self->eval_withlexicals->eval($perl);
29     };
30     1
31   }) {
32     $ok = 1;
33   } else {
34     ($ok, @ret) = (0, $@);
35   }
36   my $dumped_ret;
37   unless (eval { $dumped_ret = Dumper(@ret); 1 }) {
38     $dumped_ret = "Error dumping ${\($ok ? 'result' : 'exception')}: $@";
39     $ok = 0;
40   }
41   return {
42     stdout => $stdout, stderr => $stderr,
43     ($ok ? 'return' : 'exception') => $dumped_ret
44   };
45 }
46
47 1;