Làm cách nào tôi có thể tuyên truyền và bắt lỗi ném trong một luồng khác trong Raku?


9

Cách tốt nhất để truyền lỗi ra khỏi một luồng riêng biệt (ví dụ: khối bắt đầu, Proc :: Async hoặc phụ có chứa các lỗi này). Đơn giản chỉ cần gói mã tách ra một luồng mới trong khối try / CATCH không hoạt động và việc sử dụng chỉ chờ đợi hoạt động tùy thuộc vào giá trị trả về của thường trình con (ví dụ: tự trả về phụ sẽ không hoạt động với phương pháp chờ đợi).


Có lẽ foobarcó thể được loại bỏ ở đây?
jjmerelo

1
Tôi vẫn đang gặp vấn đề với kịch bản này ... có phải đơn giản là không thể trong Raku và yêu cầu cơ cấu lại các lớp thực tế? Điều đó sẽ không lý tưởng vì tôi không muốn xử lý lỗi cụ thể của ứng dụng trong các lớp có thể được sử dụng lại ở nơi khác ...
ryn1x

@ ryn1x Tôi đề nghị bạn xem xét khôi phục câu hỏi này về dạng ban đầu. Sau đó, thêm một ghi chú khi bắt đầu giải thích rằng, mặc dù một số câu trả lời của chúng tôi đã giải quyết được tuyên bố vấn đề được đưa ra trong nội dung câu hỏi của bạn, nhưng bạn thực sự đang tìm kiếm một cái gì đó chung chung hơn. Hơn nữa, trong khi câu trả lời bạn chấp nhận là chung chung hơn, bạn đã kết luận rằng nó vẫn chưa đủ chung chung. Hơn nữa, rằng bạn đã thử một tiền thưởng, cùng với yêu cầu tổng quát hơn, nhưng điều đó không giúp được gì. Sau đó viết một câu hỏi mới , liên kết lại với câu hỏi này, với một ví dụ mà bạn tin là minh họa cho vấn đề.
raiph

Câu trả lời hiện tại là hoàn toàn đủ cho tôi. Tôi đã thay đổi câu hỏi vì nó quá dài và cụ thể cho bất kỳ ai kết thúc ở đây.
ryn1x

Câu trả lời:


6

Sử dụng await.

Ví dụ: thay thế ba dòng này trong mã của bạn:

foo;
bar;
baz;

với:

await foo, bar, baz;

Điều này hoạt động, nhưng không mở rộng theo vấn đề thực tế của tôi bởi vì foo, bar và baz thực sự là các phương thức tự trả về. Tôi đã cập nhật câu hỏi và ví dụ.
ryn1x

5

Về mặt lý thuyết, mã đó sẽ chết :

Kể từ phiên bản 6.d của ngôn ngữ, tiền tố câu lệnh start được sử dụng trong ngữ cảnh chìm sẽ tự động đính kèm một trình xử lý ngoại lệ. Nếu một ngoại lệ xảy ra trong mã đã cho, nó sẽ được in và chương trình sẽ thoát, giống như nếu nó bị ném mà không có bất kỳ tiền tố câu lệnh bắt đầu nào liên quan.

use v6.c;
start { die }; sleep ⅓; say "hello"; # OUTPUT: «hello␤» 

use v6.d;
start { die }; sleep ⅓; say "hello";
# OUTPUT: 
# Unhandled exception in code scheduled on thread 4 
# Died 
#     in block  at -e line 1 

Trong trường hợp này, đó là một tình huống kỳ lạ bởi vì bạn không thực hiện lời hứa (bạn sẽ trả lại nó), nhưng cuối cùng bạn lại chìm đắm vì bạn đang thực hiện nó trong bối cảnh trống rỗng.

Tài liệu tương tự cung cấp cho bạn giải pháp: không nhấn chìm bối cảnh:

# Don't sink it: 
my $ = start { die }; sleep ⅓; say "hello"; # OUTPUT: «hello␤» 

# Catch yourself: 
start { die; CATCH { default { say "caught" } } };
sleep ⅓;
say "hello";

Vì chương trình của bạn không chết, tôi sẽ nói bạn đang ở tình huống thứ hai. Vì một số lý do, nó không bị chìm. Nhưng bất kể là tình huống nào, giải pháp đều giống nhau: bạn cần bắt ngoại lệ bên trong cùng một khối mã.

Giải pháp: awaitlời hứa (sẽ không nhấn chìm nó) hoặc gán nó cho một số biến, để mã xung quanh cũng chết. Nhưng trả lời OP của bạn, không, bạn không thể bắt ngoại lệ từ một luồng khác, giống như cách bạn không thể bắt ngoại lệ từ một khối khác.


Cảm ơn vì tất cả điều này. Tôi thực sự cần phải cụ thể hơn trong OP của tôi. Tôi không gọi trong bối cảnh chìm và giải pháp chờ đợi cũng không hoạt động vì các chức năng từ OP thực sự là các phương thức tự trả về. Tôi đã cập nhật câu hỏi và ví dụ.
ryn1x

4

Theo quy ước được sử dụng trong Go để vượt qua các lỗi ngoài thói quen sử dụng các kênh, tôi đã tìm thấy cách tiếp cận tương tự để làm việc trong Raku. Người ta có thể sử dụng Kênh để gửi lỗi ra khỏi mã không đồng bộ được xử lý bởi luồng chính.

Thí dụ:

my $errors = Channel.new;

my $err-supply = $errors.Supply;
$err-supply.tap(-> $e {say "handle error: $e"});

start {
    die "something went horribly wrong";

    CATCH {
        default {
            $errors.send($_);
        }
    }
}

sleep 1;
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.