Mối quan hệ giữa Failure
và Exception
là Failure
có một Exception
- có nghĩa là, nó giữ đối tượng ngoại lệ như là một phần của trạng thái của nó. Một cái gì đó như thế này:
class Failure {
has Exception $.exception;
# ...
}
Khi một Failure
"phát nổ", nó làm như vậy bằng cách ném cái Exception
bên trong nó. Do đó, những gì đạt đến CATCH
khối là Exception
đối tượng và không có liên kết trở lại kèm theo Failure
. (Trên thực tế, một Exception
đối tượng nhất định về nguyên tắc có thể được giữ bởi nhiều Failure
s.)
Do đó, không có cách nào trực tiếp để phát hiện điều này. Từ quan điểm thiết kế, có lẽ bạn không nên và nên tìm một cách khác để giải quyết vấn đề của mình. A Failure
chỉ là một cách để trì hoãn việc ném một ngoại lệ và cho phép nó được coi là một giá trị; nó không có ý định rằng bản chất của vấn đề tiềm ẩn thay đổi bởi vì nó được truyền đạt như một giá trị chứ không phải là sự chuyển giao ngay lập tức của dòng kiểm soát. Thật không may, mục tiêu ban đầu không được nêu trong câu hỏi; bạn có thể thấy hữu ích khi xem xét các ngoại lệ kiểm soát, nhưng nếu không thì có thể đăng một câu hỏi khác về vấn đề tiềm ẩn mà bạn đang cố gắng giải quyết. Có lẽ có một cách tốt hơn.
Để đầy đủ, tôi sẽ lưu ý rằng có những cách gián tiếp mà người ta có thể phát hiện ra rằng nó Exception
đã bị ném bởi a Failure
. Ví dụ: nếu bạn có được .backtrace
đối tượng ngoại lệ và nhìn vào gói của khung trên cùng, có thể xác định rằng nó đến từ Failure
:
sub foo() { fail X::AdHoc.new(message => "foo") }
try {
foo();
CATCH {
note do { no fatal; .backtrace[0].code.package ~~ Failure };
.resume
}
}
Tuy nhiên, điều này phụ thuộc rất nhiều vào các chi tiết triển khai có thể dễ dàng thay đổi, vì vậy tôi không dựa vào nó.