处理异常

楽土

经过一番反反复复,我找到了一个实用的方法来处理 Shell::Piping 中的错误条件。这个实用的方法是有多个方法。一个进程确实有一个 exitinteger(称为代码,因为它可能很神秘)和文本输出到 STDERR 来表示出了问题。有时我们需要粗心的错误处理,有时我们需要研究文本输出并对其做出反应。

我发现了一个非常好的方法,使用 Junction 和 Raku 的类型系统来从错误处理中去除一些模板。将两者结合起来,我们可以创建一个灵活的类型。

class Exitcode {
    has $.value;
    has $.command;
    method Numeric { $.value }
    method Str { $.command }
}

所以这个类产生的对象既是一个数字又是一个文本。实际看的是什么,要看是谁在看。我们可以使用 infix:<~~> 来决定使用哪个比较运算符。

say $ex ~~ 42 && $ex ~~ ‚find‘; # OUTPUT: True

这还是挺啰嗦的。我们可以用 Juncttion,因为它结合得比 ~~ 较紧。

say $ex ~~ 42 & ‚find‘; # OUTPUT: True

现在,我们可以 CATCH 一个异常,并缩小管道中的命令,很容易失败。

CATCH {
    when X::Shell::NonZeroExitcode {
        given .exitcode {
            when 42 & ‚find‘ {
                warn ‚Oh now! We found the answer!‘;
            }
        }
    }
}

并不是所有模块的用户都可能喜欢使用 Exception。所以我们在 Shell::Pipe 对象中使用一个构造来创建一个 Failure 从 .sink 返回。如果调用了 Shell::Pipe.exitcode 方法,我们就会认为用户是在用手处理它们。然后,我们可以调用 .handled 来"中止"这个 Exception。这一点必须简单,否则可能会被跳过。因此,在 Exitcode 这个类中,强转器方法的使用很不寻常。

comments powered by Disqus