From f4cad2123b2af0de72bda4ce039e16e74f163f4e Mon Sep 17 00:00:00 2001 From: nsfisis Date: Sat, 8 Aug 2026 22:14:12 +0900 Subject: feat(php-shim): give ported exceptions PHP's class hierarchy Ported exceptions were flat structs reached with `downcast_ref`, so Composer's `catch (\RuntimeException $e)` only matched the exact leaf type and `get_class($e)` had nothing to report. Each exception now embeds an instance of the class it extends and travels inside an `AnyThrowable`; `Catch::catch`/`catch_mut` walk that chain, and `PhpClass::php_class_name` yields the PHP FQCN. Dropping the `std::error::Error` impls from the exception types leaves `AnyThrowable` as the only route into an `anyhow::Error`, so the walk cannot be bypassed. A `no_exception_downcast` linter catches the `downcast::()` calls that would now silently answer `None`. Three sites change behavior as a result: the `TransportException` exit-code override reaches `MaxFileSizeExceededException`, the `catch (\LogicException)` in findSimilar() reaches its subclasses, and rendered exception titles carry the real class name rather than a guess. `get_class_err()` is no longer a `todo!()`, which re-enables FilesystemRepositoryTest::testCorruptedRepositoryFile. Co-Authored-By: Claude Opus 5 (1M context) --- .../src/repository/filesystem_repository.rs | 47 ++++++++++------------ 1 file changed, 21 insertions(+), 26 deletions(-) (limited to 'crates/shirabe/src/repository/filesystem_repository.rs') diff --git a/crates/shirabe/src/repository/filesystem_repository.rs b/crates/shirabe/src/repository/filesystem_repository.rs index 47241bde..d9085bfd 100644 --- a/crates/shirabe/src/repository/filesystem_repository.rs +++ b/crates/shirabe/src/repository/filesystem_repository.rs @@ -19,9 +19,9 @@ use crate::util::Filesystem; use crate::util::Platform; use indexmap::IndexMap; use shirabe_php_shim::{ - Exception, InvalidArgumentException, LogicException, PhpMixed, UnexpectedValueException, - array_flip, dirname, get_class_err, get_debug_type, in_array_strict, is_array, is_null, - is_string, ksort, realpath, str_repeat, usort, var_export, + AnyThrowable, InvalidArgumentException, LogicException, PhpClass as _, PhpMixed, + UnexpectedValueException, array_flip, dirname, get_debug_type, in_array_strict, is_array, + is_null, is_string, ksort, realpath, str_repeat, usort, var_export, }; use shirabe_semver::constraint::AnyConstraint; @@ -57,10 +57,9 @@ impl FilesystemRepository { let filesystem = filesystem .unwrap_or_else(|| std::rc::Rc::new(std::cell::RefCell::new(Filesystem::new(None)))); if dump_versions && root_package.is_none() { - return Err(InvalidArgumentException { - message: "Expected a root package instance if $dumpVersions is true".to_string(), - code: 0, - } + return Err(InvalidArgumentException::new( + "Expected a root package instance if $dumpVersions is true".to_string(), + ) .into()); } Ok(Self { @@ -134,10 +133,9 @@ impl FilesystemRepository { } if !is_array(&packages_value) { - return Err(UnexpectedValueException { - message: "Could not parse package list from the repository".to_string(), - code: 0, - } + return Err(UnexpectedValueException::new( + "Could not parse package list from the repository".to_string(), + ) .into()); } @@ -145,15 +143,14 @@ impl FilesystemRepository { })() { Ok(p) => p, Err(e) => { - return Err(InvalidRepositoryException(Exception { - message: format!( - "Invalid repository data in {}, packages could not be loaded: [{}] {}", - self.file.get_path(), - get_class_err(&e), - e, - ), - code: 0, - }) + return Err(InvalidRepositoryException::new(format!( + "Invalid repository data in {}, packages could not be loaded: [{}] {}", + self.file.get_path(), + AnyThrowable::of(e.as_ref()) + .expect("PHP reaches this only with a caught \\Throwable") + .php_class_name(), + e, + )) .into()); } }; @@ -464,12 +461,10 @@ impl FilesystemRepository { self.inner.get_packages()?.into_iter().collect(); let mut current_root: RootPackageInterfaceHandle = match &self.root_package { None => { - return Err(LogicException { - message: - "It should not be possible to dump packages if no root package is given" - .to_string(), - code: 0, - } + return Err(LogicException::new( + "It should not be possible to dump packages if no root package is given" + .to_string(), + ) .into()); } Some(r) => r.clone(), -- cgit v1.3.1-4-g156e