From a38ed045e9981664d90c05ab43ab4ab6026eb31b Mon Sep 17 00:00:00 2001 From: nsfisis Date: Sun, 30 Aug 2026 23:57:25 +0900 Subject: feat(plugin): carry an exception's class and state across the boundary A Rust-side failure reached plugin code as a RuntimeException whose message carried the name of the call that failed, so `catch (TransportException $e)` never matched and the status code the plugin branches on was gone. The Throw frame now names the class the exception was thrown as and carries the state that class declares beyond message and code. \Shirabe\MaterializedThrowable rebuilds it in the child: `new $class($message, $code)` for a class whose constructor has \Exception's shape, then the properties by reflection. A class the child cannot build that way keeps the RuntimeException shape. Co-Authored-By: Claude Opus 5 (1M context) --- .../fixtures/e2e-exception/project/composer.json | 24 ++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 crates/shirabe/tests/plugin/fixtures/e2e-exception/project/composer.json (limited to 'crates/shirabe/tests/plugin/fixtures/e2e-exception/project/composer.json') diff --git a/crates/shirabe/tests/plugin/fixtures/e2e-exception/project/composer.json b/crates/shirabe/tests/plugin/fixtures/e2e-exception/project/composer.json new file mode 100644 index 00000000..da06cc93 --- /dev/null +++ b/crates/shirabe/tests/plugin/fixtures/e2e-exception/project/composer.json @@ -0,0 +1,24 @@ +{ + "name": "shirabe/e2e-exception", + "description": "E2E fixture project: record the exceptions a plugin catches from Composer services.", + "repositories": [ + { + "type": "path", + "url": "../plugin", + "options": { + "symlink": false + } + }, + { + "packagist.org": false + } + ], + "require": { + "shirabe-test/exception-probe": "1.0.0" + }, + "config": { + "allow-plugins": { + "shirabe-test/exception-probe": true + } + } +} -- cgit v1.3.1-4-g156e