| Age | Commit message (Collapse) | Author |
|
`ProcessExecutor::execute_args` existed only to turn `execute`'s
`anyhow::Result` into an exit code of 1, so every one of its ~87 call
sites silently took the "command failed" branch on an error PHP would
have thrown. It is gone; callers use `execute` and propagate with `?`.
Where the enclosing function had no `Result` to propagate into, its
signature grew one, up to and including `Git::get_version`,
`Svn::binary_version`, `GitHub`/`GitLab`/`Bitbucket::authorize_oauth`,
`InitCommand::get_git_config` and `DiagnoseCommand::check_git`.
The VCS drivers had the same problem in the other direction: their
`get_contents` returned `Result<Response, Box<TransportException>>`, a
type too narrow for the PHP method, which lets any Throwable out of the
`catch (TransportException $e)` block. Every non-transport error was
therefore rewritten into a `TransportException` with code 0, which the
callers switch on. They now return
`anyhow::Result<Result<Response, Box<TransportException>>>`: the outer
`Result` carries what PHP does not catch, the inner one the exception
the drivers handle.
That signature also restores `GitLabDriver::getContents`: the 400/401
`TransportException`s it raises to force authentication are thrown
inside its own `try` block and handled by its own `catch`, but the port
returned them straight to the caller, so the authentication flow behind
them never ran.
`impl_php_exception!` gains `From<Box<$ty>> for anyhow::Error` so a
caught exception can be re-propagated with `?`.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
|
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
|
Composer hands the exception it caught to the one it throws in its place,
so `getPrevious()` reaches the cause and Application's renderer prints the
whole chain. Every ported site dropped it, because the flat exception
structs had nowhere to put one. `AnyThrowable::into_previous` turns the
caught error into that argument, and the 13 sites now pass it.
`getCode()` came along for the ride at the four sites that derive the new
exception's code from the caught one (PharArchiver, ArrayLoader x2), and
ComposerRepository's message now names the caught exception's class
instead of the literal "Exception".
GitHubDriver::attemptCloneFallback took the previous exception's message
and appended it to its own, which no `\RuntimeException('Fallback to git
driver disabled')` in Composer ever says; it now chains it instead.
Git::syncMirror restores what PHP's `finally` does to an exception in
flight: the `git remote set-url` that scrubs credentials back out of the
URL runs in a `finally`, and when it fails PHP propagates *its* exception
over the one already leaving, chaining the displaced one as previous. The
port discarded the finally's result, so a failure to scrub the URL was
reported as a successful mirror sync. `AnyThrowable::set_previous`
models the engine-level chaining.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
|
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::<X>()` 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) <noreply@anthropic.com>
|
|
|