aboutsummaryrefslogtreecommitdiffhomepage
path: root/crates/shirabe
diff options
context:
space:
mode:
Diffstat (limited to 'crates/shirabe')
-rw-r--r--crates/shirabe/src/advisory/audit_config.rs11
-rw-r--r--crates/shirabe/src/advisory/auditor.rs28
-rw-r--r--crates/shirabe/src/autoload/autoload_generator.rs10
-rw-r--r--crates/shirabe/src/autoload/class_loader.rs16
-rw-r--r--crates/shirabe/src/cache.rs4
-rw-r--r--crates/shirabe/src/command/archive_command.rs11
-rw-r--r--crates/shirabe/src/command/audit_command.rs28
-rw-r--r--crates/shirabe/src/command/base_command.rs77
-rw-r--r--crates/shirabe/src/command/base_dependency_command.rs20
-rw-r--r--crates/shirabe/src/command/bump_command.rs16
-rw-r--r--crates/shirabe/src/command/config_command.rs184
-rw-r--r--crates/shirabe/src/command/create_project_command.rs84
-rw-r--r--crates/shirabe/src/command/diagnose_command.rs74
-rw-r--r--crates/shirabe/src/command/dump_autoload_command.rs20
-rw-r--r--crates/shirabe/src/command/exec_command.rs19
-rw-r--r--crates/shirabe/src/command/global_command.rs22
-rw-r--r--crates/shirabe/src/command/init_command.rs83
-rw-r--r--crates/shirabe/src/command/licenses_command.rs16
-rw-r--r--crates/shirabe/src/command/package_discovery_trait.rs148
-rw-r--r--crates/shirabe/src/command/reinstall_command.rs18
-rw-r--r--crates/shirabe/src/command/remove_command.rs21
-rw-r--r--crates/shirabe/src/command/repository_command.rs127
-rw-r--r--crates/shirabe/src/command/require_command.rs11
-rw-r--r--crates/shirabe/src/command/run_script_command.rs38
-rw-r--r--crates/shirabe/src/command/script_alias_command.rs17
-rw-r--r--crates/shirabe/src/command/search_command.rs7
-rw-r--r--crates/shirabe/src/command/show_command.rs46
-rw-r--r--crates/shirabe/src/command/update_command.rs27
-rw-r--r--crates/shirabe/src/config.rs70
-rw-r--r--crates/shirabe/src/config/json_config_source.rs49
-rw-r--r--crates/shirabe/src/console/application.rs260
-rw-r--r--crates/shirabe/src/dependency_resolver/decisions.rs15
-rw-r--r--crates/shirabe/src/dependency_resolver/generic_rule.rs6
-rw-r--r--crates/shirabe/src/dependency_resolver/multi_conflict_rule.rs13
-rw-r--r--crates/shirabe/src/dependency_resolver/pool_builder.rs15
-rw-r--r--crates/shirabe/src/dependency_resolver/problem.rs7
-rw-r--r--crates/shirabe/src/dependency_resolver/request.rs15
-rw-r--r--crates/shirabe/src/dependency_resolver/rule.rs11
-rw-r--r--crates/shirabe/src/dependency_resolver/rule_set.rs6
-rw-r--r--crates/shirabe/src/dependency_resolver/rule_set_generator.rs12
-rw-r--r--crates/shirabe/src/dependency_resolver/solver.rs14
-rw-r--r--crates/shirabe/src/dependency_resolver/solver_bug_exception.rs17
-rw-r--r--crates/shirabe/src/dependency_resolver/solver_problems_exception.rs28
-rw-r--r--crates/shirabe/src/downloader/archive_downloader.rs16
-rw-r--r--crates/shirabe/src/downloader/download_manager.rs71
-rw-r--r--crates/shirabe/src/downloader/file_downloader.rs54
-rw-r--r--crates/shirabe/src/downloader/filesystem_exception.rs18
-rw-r--r--crates/shirabe/src/downloader/fossil_downloader.rs24
-rw-r--r--crates/shirabe/src/downloader/git_downloader.rs188
-rw-r--r--crates/shirabe/src/downloader/gzip_downloader.rs5
-rw-r--r--crates/shirabe/src/downloader/hg_downloader.rs44
-rw-r--r--crates/shirabe/src/downloader/max_file_size_exceeded_exception.rs14
-rw-r--r--crates/shirabe/src/downloader/path_downloader.rs100
-rw-r--r--crates/shirabe/src/downloader/rar_downloader.rs27
-rw-r--r--crates/shirabe/src/downloader/svn_downloader.rs73
-rw-r--r--crates/shirabe/src/downloader/transport_exception.rs34
-rw-r--r--crates/shirabe/src/downloader/vcs_downloader.rs78
-rw-r--r--crates/shirabe/src/downloader/zip_downloader.rs84
-rw-r--r--crates/shirabe/src/event_dispatcher/event_dispatcher.rs172
-rw-r--r--crates/shirabe/src/event_dispatcher/script_execution_exception.rs20
-rw-r--r--crates/shirabe/src/exception/irrecoverable_download_exception.rs12
-rw-r--r--crates/shirabe/src/exception/no_ssl_exception.rs8
-rw-r--r--crates/shirabe/src/factory.rs97
-rw-r--r--crates/shirabe/src/filter/platform_requirement_filter/platform_requirement_filter_factory.rs11
-rw-r--r--crates/shirabe/src/installed_versions.rs45
-rw-r--r--crates/shirabe/src/installer.rs36
-rw-r--r--crates/shirabe/src/installer/installation_manager.rs6
-rw-r--r--crates/shirabe/src/installer/library_installer.rs25
-rw-r--r--crates/shirabe/src/installer/metapackage_installer.rs16
-rw-r--r--crates/shirabe/src/installer/noop_installer.rs16
-rw-r--r--crates/shirabe/src/installer/plugin_installer.rs11
-rw-r--r--crates/shirabe/src/installer/project_installer.rs20
-rw-r--r--crates/shirabe/src/io/base_io.rs12
-rw-r--r--crates/shirabe/src/io/buffer_io.rs19
-rw-r--r--crates/shirabe/src/io/console_io.rs11
-rw-r--r--crates/shirabe/src/json/json_file.rs71
-rw-r--r--crates/shirabe/src/json/json_manipulator.rs35
-rw-r--r--crates/shirabe/src/json/json_validation_exception.rs18
-rw-r--r--crates/shirabe/src/package/alias_package.rs7
-rw-r--r--crates/shirabe/src/package/archiver/archivable_files_finder.rs8
-rw-r--r--crates/shirabe/src/package/archiver/archive_manager.rs16
-rw-r--r--crates/shirabe/src/package/archiver/phar_archiver.rs18
-rw-r--r--crates/shirabe/src/package/archiver/zip_archiver.rs2
-rw-r--r--crates/shirabe/src/package/loader/array_loader.rs94
-rw-r--r--crates/shirabe/src/package/loader/invalid_package_exception.rs14
-rw-r--r--crates/shirabe/src/package/loader/json_loader.rs5
-rw-r--r--crates/shirabe/src/package/loader/root_package_loader.rs30
-rw-r--r--crates/shirabe/src/package/loader/validating_array_loader.rs5
-rw-r--r--crates/shirabe/src/package/locker.rs47
-rw-r--r--crates/shirabe/src/package/package.rs7
-rw-r--r--crates/shirabe/src/package/version/version_guesser.rs7
-rw-r--r--crates/shirabe/src/package/version/version_selector.rs11
-rw-r--r--crates/shirabe/src/plugin/php_plugin_proxy.rs118
-rw-r--r--crates/shirabe/src/plugin/plugin_blocked_exception.rs14
-rw-r--r--crates/shirabe/src/plugin/plugin_manager.rs84
-rw-r--r--crates/shirabe/src/question/strict_confirmation_question.rs7
-rw-r--r--crates/shirabe/src/repository/artifact_repository.rs26
-rw-r--r--crates/shirabe/src/repository/composer_repository.rs208
-rw-r--r--crates/shirabe/src/repository/filesystem_repository.rs47
-rw-r--r--crates/shirabe/src/repository/filter_repository.rs44
-rw-r--r--crates/shirabe/src/repository/invalid_repository_exception.rs14
-rw-r--r--crates/shirabe/src/repository/package_repository.rs25
-rw-r--r--crates/shirabe/src/repository/path_repository.rs38
-rw-r--r--crates/shirabe/src/repository/platform_repository.rs52
-rw-r--r--crates/shirabe/src/repository/repository_factory.rs62
-rw-r--r--crates/shirabe/src/repository/repository_manager.rs16
-rw-r--r--crates/shirabe/src/repository/repository_security_exception.rs12
-rw-r--r--crates/shirabe/src/repository/repository_set.rs35
-rw-r--r--crates/shirabe/src/repository/vcs/forgejo_driver.rs62
-rw-r--r--crates/shirabe/src/repository/vcs/fossil_driver.rs63
-rw-r--r--crates/shirabe/src/repository/vcs/git_bitbucket_driver.rs38
-rw-r--r--crates/shirabe/src/repository/vcs/git_driver.rs78
-rw-r--r--crates/shirabe/src/repository/vcs/github_driver.rs60
-rw-r--r--crates/shirabe/src/repository/vcs/gitlab_driver.rs56
-rw-r--r--crates/shirabe/src/repository/vcs/hg_driver.rs41
-rw-r--r--crates/shirabe/src/repository/vcs/perforce_driver.rs14
-rw-r--r--crates/shirabe/src/repository/vcs/svn_driver.rs39
-rw-r--r--crates/shirabe/src/repository/vcs/vcs_driver.rs21
-rw-r--r--crates/shirabe/src/repository/vcs_repository.rs19
-rw-r--r--crates/shirabe/src/self_update/versions.rs24
-rw-r--r--crates/shirabe/src/util/auth_helper.rs6
-rw-r--r--crates/shirabe/src/util/bitbucket.rs49
-rw-r--r--crates/shirabe/src/util/config_validator.rs5
-rw-r--r--crates/shirabe/src/util/error_handler.rs8
-rw-r--r--crates/shirabe/src/util/filesystem.rs98
-rw-r--r--crates/shirabe/src/util/forgejo.rs5
-rw-r--r--crates/shirabe/src/util/forgejo_url.rs8
-rw-r--r--crates/shirabe/src/util/git.rs36
-rw-r--r--crates/shirabe/src/util/github.rs3
-rw-r--r--crates/shirabe/src/util/gitlab.rs34
-rw-r--r--crates/shirabe/src/util/http/curl_downloader.rs58
-rw-r--r--crates/shirabe/src/util/http/proxy_item.rs34
-rw-r--r--crates/shirabe/src/util/http/proxy_manager.rs6
-rw-r--r--crates/shirabe/src/util/http/request_proxy.rs9
-rw-r--r--crates/shirabe/src/util/http_downloader.rs26
-rw-r--r--crates/shirabe/src/util/no_proxy_pattern.rs49
-rw-r--r--crates/shirabe/src/util/perforce.rs37
-rw-r--r--crates/shirabe/src/util/platform.rs13
-rw-r--r--crates/shirabe/src/util/process_executor.rs49
-rw-r--r--crates/shirabe/src/util/remote_filesystem.rs48
-rw-r--r--crates/shirabe/src/util/stream_context_factory.rs26
-rw-r--r--crates/shirabe/src/util/svn.rs31
-rw-r--r--crates/shirabe/src/util/tar.rs36
-rw-r--r--crates/shirabe/src/util/zip.rs39
-rw-r--r--crates/shirabe/tests/downloader/download_manager_test.rs8
-rw-r--r--crates/shirabe/tests/downloader/file_downloader_test.rs9
-rw-r--r--crates/shirabe/tests/event_dispatcher/event_dispatcher_test.rs7
-rw-r--r--crates/shirabe/tests/json/composer_schema_test.rs3
-rw-r--r--crates/shirabe/tests/json/json_file_test.rs23
-rw-r--r--crates/shirabe/tests/package/archiver/archive_manager_test.rs6
-rw-r--r--crates/shirabe/tests/package/loader/validating_array_loader_test.rs3
-rw-r--r--crates/shirabe/tests/package/locker_test.rs5
-rw-r--r--crates/shirabe/tests/plugin/plugin_installer_test.rs4
-rw-r--r--crates/shirabe/tests/repository/filesystem_repository_test.rs4
-rw-r--r--crates/shirabe/tests/repository/vcs/git_bitbucket_driver_test.rs7
-rw-r--r--crates/shirabe/tests/repository/vcs/git_driver_test.rs5
-rw-r--r--crates/shirabe/tests/repository/vcs/hg_driver_test.rs5
-rw-r--r--crates/shirabe/tests/repository/vcs/svn_driver_test.rs5
-rw-r--r--crates/shirabe/tests/util/auth_helper_test.rs5
-rw-r--r--crates/shirabe/tests/util/git_test.rs3
-rw-r--r--crates/shirabe/tests/util/http_downloader_test.rs3
-rw-r--r--crates/shirabe/tests/util/silencer_test.rs6
162 files changed, 2252 insertions, 3372 deletions
diff --git a/crates/shirabe/src/advisory/audit_config.rs b/crates/shirabe/src/advisory/audit_config.rs
index 71730317..fc1cbedb 100644
--- a/crates/shirabe/src/advisory/audit_config.rs
+++ b/crates/shirabe/src/advisory/audit_config.rs
@@ -103,13 +103,10 @@ impl AuditConfig {
.map(|s| s.to_string());
if !["audit", "block", "all"].contains(&apply.as_str()) {
- return Err(InvalidArgumentException {
- message: format!(
- "Invalid 'apply' value for '{}': {}. Expected 'audit', 'block', or 'all'.",
- key, apply
- ),
- code: 0,
- }.into());
+ return Err(InvalidArgumentException::new(format!(
+ "Invalid 'apply' value for '{}': {}. Expected 'audit', 'block', or 'all'.",
+ key, apply
+ )).into());
}
(key.clone(), apply, reason)
diff --git a/crates/shirabe/src/advisory/auditor.rs b/crates/shirabe/src/advisory/auditor.rs
index d20c9453..d661cf90 100644
--- a/crates/shirabe/src/advisory/auditor.rs
+++ b/crates/shirabe/src/advisory/auditor.rs
@@ -422,13 +422,10 @@ impl Auditor {
.map(|buffer_io| &buffer_io.inner)
});
if io_as_console.is_none() {
- return Err(InvalidArgumentException {
- message: format!(
- "Cannot use table format with {}",
- get_class(&PhpMixed::Null)
- ),
- code: 0,
- }
+ return Err(InvalidArgumentException::new(format!(
+ "Cannot use table format with {}",
+ get_class(&PhpMixed::Null)
+ ))
.into());
}
self.output_advisories_table(io_as_console.unwrap(), advisories)?;
@@ -441,11 +438,9 @@ impl Auditor {
Ok(())
}
Self::FORMAT_SUMMARY => Ok(()),
- _ => Err(InvalidArgumentException {
- message: format!("Invalid format \"{}\".", format),
- code: 0,
+ _ => {
+ Err(InvalidArgumentException::new(format!("Invalid format \"{}\".", format)).into())
}
- .into()),
}
}
@@ -597,13 +592,10 @@ impl Auditor {
.map(|buffer_io| &buffer_io.inner)
});
if io_as_console.is_none() {
- return Err(InvalidArgumentException {
- message: format!(
- "Cannot use table format with {}",
- get_class(&PhpMixed::Null)
- ),
- code: 0,
- }
+ return Err(InvalidArgumentException::new(format!(
+ "Cannot use table format with {}",
+ get_class(&PhpMixed::Null)
+ ))
.into());
}
diff --git a/crates/shirabe/src/autoload/autoload_generator.rs b/crates/shirabe/src/autoload/autoload_generator.rs
index aacbfc0f..4eae319d 100644
--- a/crates/shirabe/src/autoload/autoload_generator.rs
+++ b/crates/shirabe/src/autoload/autoload_generator.rs
@@ -815,19 +815,13 @@ return array(
{
let name = package.get_name();
let _ = package.get_target_dir();
- return Err(InvalidArgumentException {
- message: format!("PSR-4 autoloading is incompatible with the target-dir property, remove the target-dir in package '{}'.", name),
- code: 0,
- }
+ return Err(InvalidArgumentException::new(format!("PSR-4 autoloading is incompatible with the target-dir property, remove the target-dir in package '{}'.", name))
.into());
}
if let Some(psr4) = autoload.get("psr-4").and_then(|v| v.as_array()) {
for (namespace, _dirs) in psr4 {
if !namespace.is_empty() && !namespace.ends_with('\\') {
- return Err(InvalidArgumentException {
- message: format!("psr-4 namespaces must end with a namespace separator, '{}' does not, use '{}\\'.", namespace, namespace),
- code: 0,
- }
+ return Err(InvalidArgumentException::new(format!("psr-4 namespaces must end with a namespace separator, '{}' does not, use '{}\\'.", namespace, namespace))
.into());
}
}
diff --git a/crates/shirabe/src/autoload/class_loader.rs b/crates/shirabe/src/autoload/class_loader.rs
index 89758269..47b6ee4c 100644
--- a/crates/shirabe/src/autoload/class_loader.rs
+++ b/crates/shirabe/src/autoload/class_loader.rs
@@ -175,11 +175,9 @@ impl ClassLoader {
// Register directories for a new namespace.
let length = strlen(prefix);
if "\\" != &prefix[(length as usize - 1)..(length as usize)] {
- return Err(InvalidArgumentException {
- message: "A non-empty PSR-4 prefix must end with a namespace separator."
- .to_string(),
- code: 0,
- }
+ return Err(InvalidArgumentException::new(
+ "A non-empty PSR-4 prefix must end with a namespace separator.".to_string(),
+ )
.into());
}
let first = prefix.chars().next().unwrap_or('\0').to_string();
@@ -226,11 +224,9 @@ impl ClassLoader {
} else {
let length = strlen(prefix);
if "\\" != &prefix[(length as usize - 1)..(length as usize)] {
- return Err(InvalidArgumentException {
- message: "A non-empty PSR-4 prefix must end with a namespace separator."
- .to_string(),
- code: 0,
- }
+ return Err(InvalidArgumentException::new(
+ "A non-empty PSR-4 prefix must end with a namespace separator.".to_string(),
+ )
.into());
}
let first = prefix.chars().next().unwrap_or('\0').to_string();
diff --git a/crates/shirabe/src/cache.rs b/crates/shirabe/src/cache.rs
index 354e559e..a9f56eac 100644
--- a/crates/shirabe/src/cache.rs
+++ b/crates/shirabe/src/cache.rs
@@ -180,7 +180,7 @@ impl Cache {
self.io.write_error3(
&format!(
"<warning>Failed to write into cache: {}</warning>",
- e.message
+ e.get_message()
),
true,
crate::io::DEBUG,
@@ -190,7 +190,7 @@ impl Cache {
php_regex!(
r"{^file_put_contents\(\): Only ([0-9]+) of ([0-9]+) bytes written}"
),
- &e.message,
+ e.get_message(),
Some(&mut m),
) {
// Remove partial file.
diff --git a/crates/shirabe/src/command/archive_command.rs b/crates/shirabe/src/command/archive_command.rs
index e749d13f..1c428c58 100644
--- a/crates/shirabe/src/command/archive_command.rs
+++ b/crates/shirabe/src/command/archive_command.rs
@@ -303,13 +303,10 @@ impl ArchiveCommand {
};
let Some(complete) = package.as_complete() else {
- return Err(LogicException {
- message: format!(
- "Expected a CompletePackageInterface instance but found {}",
- get_debug_type(&shirabe_php_shim::PhpMixed::Null)
- ),
- code: 0,
- }
+ return Err(LogicException::new(format!(
+ "Expected a CompletePackageInterface instance but found {}",
+ get_debug_type(&shirabe_php_shim::PhpMixed::Null)
+ ))
.into());
};
diff --git a/crates/shirabe/src/command/audit_command.rs b/crates/shirabe/src/command/audit_command.rs
index 0eee0036..268984d6 100644
--- a/crates/shirabe/src/command/audit_command.rs
+++ b/crates/shirabe/src/command/audit_command.rs
@@ -60,10 +60,7 @@ impl AuditCommand {
let locker = composer.get_locker().clone();
let mut locker = locker.borrow_mut();
if !locker.is_locked() {
- return Err(UnexpectedValueException {
- message: "Valid composer.json and composer.lock files are required to run this command with --locked".to_string(),
- code: 0,
- }.into());
+ return Err(UnexpectedValueException::new("Valid composer.json and composer.lock files are required to run this command with --locked".to_string()).into());
}
let locked_repo = locker.get_locked_repository(
!input
@@ -228,19 +225,16 @@ impl Command for AuditCommand {
.collect::<Vec<_>>(),
)
{
- return Err(InvalidArgumentException {
- message: format!(
- "--abandoned must be one of {}.",
- implode(
- ", ",
- &Auditor::ABANDONEDS
- .iter()
- .map(|s| s.to_string())
- .collect::<Vec<_>>()
- )
- ),
- code: 0,
- }
+ return Err(InvalidArgumentException::new(format!(
+ "--abandoned must be one of {}.",
+ implode(
+ ", ",
+ &Auditor::ABANDONEDS
+ .iter()
+ .map(|s| s.to_string())
+ .collect::<Vec<_>>()
+ )
+ ))
.into());
}
diff --git a/crates/shirabe/src/command/base_command.rs b/crates/shirabe/src/command/base_command.rs
index 7a66862e..a1de9783 100644
--- a/crates/shirabe/src/command/base_command.rs
+++ b/crates/shirabe/src/command/base_command.rs
@@ -294,10 +294,7 @@ impl BaseCommand for BaseCommandData {
if self.composer.borrow().is_none() {
let application = self.get_application();
let Some(application) = application else {
- return Err(RuntimeException {
- message: "Could not create a Composer\\Composer instance, you must inject one if this command is not used with a Composer\\Console\\Application instance".to_string(),
- code: 0,
- }
+ return Err(RuntimeException::new("Could not create a Composer\\Composer instance, you must inject one if this command is not used with a Composer\\Console\\Application instance".to_string())
.into());
};
let composer = {
@@ -455,11 +452,9 @@ impl BaseCommand for BaseCommandData {
.as_bool()
.unwrap_or(false)
{
- return Err(InvalidArgumentException {
- message: "--prefer-source can not be used together with --prefer-install"
- .to_string(),
- code: 0,
- }
+ return Err(InvalidArgumentException::new(
+ "--prefer-source can not be used together with --prefer-install".to_string(),
+ )
.into());
}
if input
@@ -468,11 +463,9 @@ impl BaseCommand for BaseCommandData {
.as_bool()
.unwrap_or(false)
{
- return Err(InvalidArgumentException {
- message: "--prefer-dist can not be used together with --prefer-install"
- .to_string(),
- code: 0,
- }
+ return Err(InvalidArgumentException::new(
+ "--prefer-dist can not be used together with --prefer-install".to_string(),
+ )
.into());
}
let prefer_install = input.borrow().get_option("prefer-install")?;
@@ -492,13 +485,10 @@ impl BaseCommand for BaseCommandData {
prefer_source = false;
}
other => {
- return Err(UnexpectedValueException {
- message: format!(
- "--prefer-install accepts one of \"dist\", \"source\" or \"auto\", got {}",
- other
- ),
- code: 0,
- }
+ return Err(UnexpectedValueException::new(format!(
+ "--prefer-install accepts one of \"dist\", \"source\" or \"auto\", got {}",
+ other
+ ))
.into());
}
}
@@ -551,12 +541,8 @@ impl BaseCommand for BaseCommandData {
if !input.borrow().has_option("ignore-platform-reqs")
|| !input.borrow().has_option("ignore-platform-req")
{
- return Err(LogicException {
- message:
- "Calling getPlatformRequirementFilter from a command which does not define the --ignore-platform-req[s] flags is not permitted."
- .to_string(),
- code: 0,
- }
+ return Err(LogicException::new("Calling getPlatformRequirementFilter from a command which does not define the --ignore-platform-req[s] flags is not permitted."
+ .to_string())
.into());
}
@@ -585,14 +571,11 @@ impl BaseCommand for BaseCommandData {
let requirements = self.normalize_requirements(requirements)?;
for requirement in requirements {
if !requirement.contains_key("version") {
- return Err(UnexpectedValueException {
- message: format!(
- "Option {} is missing a version constraint, use e.g. {}:^1.0",
- requirement.get("name").map(|s| s.as_str()).unwrap_or(""),
- requirement.get("name").map(|s| s.as_str()).unwrap_or(""),
- ),
- code: 0,
- }
+ return Err(UnexpectedValueException::new(format!(
+ "Option {} is missing a version constraint, use e.g. {}:^1.0",
+ requirement.get("name").map(|s| s.as_str()).unwrap_or(""),
+ requirement.get("name").map(|s| s.as_str()).unwrap_or(""),
+ ))
.into());
}
requires.insert(
@@ -648,13 +631,10 @@ impl BaseCommand for BaseCommandData {
opt_name: &str,
) -> anyhow::Result<String> {
if !input.borrow().has_option(opt_name) {
- return Err(LogicException {
- message: format!(
- "This should not be called on a Command which has no {} option defined.",
- opt_name
- ),
- code: 0,
- }
+ return Err(LogicException::new(format!(
+ "This should not be called on a Command which has no {} option defined.",
+ opt_name
+ ))
.into());
}
@@ -664,14 +644,11 @@ impl BaseCommand for BaseCommandData {
.map(|s| PhpMixed::String(s.to_string()))
.collect();
if !in_array_strict(val.clone(), &formats) {
- return Err(InvalidArgumentException {
- message: format!(
- "--{} must be one of {}.",
- opt_name,
- Auditor::FORMATS.join(", ")
- ),
- code: 0,
- }
+ return Err(InvalidArgumentException::new(format!(
+ "--{} must be one of {}.",
+ opt_name,
+ Auditor::FORMATS.join(", ")
+ ))
.into());
}
diff --git a/crates/shirabe/src/command/base_dependency_command.rs b/crates/shirabe/src/command/base_dependency_command.rs
index 46cc654f..e46cac8c 100644
--- a/crates/shirabe/src/command/base_dependency_command.rs
+++ b/crates/shirabe/src/command/base_dependency_command.rs
@@ -63,12 +63,11 @@ pub trait BaseDependencyCommand: BaseCommand {
let mut locker = locker.borrow_mut();
if !locker.is_locked() {
- return Err(anyhow::anyhow!(UnexpectedValueException {
- message:
- "A valid composer.lock file is required to run this command with --locked"
- .to_string(),
- code: 0,
- }));
+ return Err(UnexpectedValueException::new(
+ "A valid composer.lock file is required to run this command with --locked"
+ .to_string(),
+ )
+ .into());
}
repos.push(locker.get_locked_repository(true)?.into());
@@ -134,10 +133,11 @@ pub trait BaseDependencyCommand: BaseCommand {
let packages = installed_repo.find_packages_with_replacers_and_providers(&needle, None)?;
if packages.is_empty() {
- return Err(anyhow::anyhow!(InvalidArgumentException {
- message: format!("Could not find package \"{}\" in your project", needle),
- code: 0,
- }));
+ return Err(InvalidArgumentException::new(format!(
+ "Could not find package \"{}\" in your project",
+ needle
+ ))
+ .into());
}
let matched_package = installed_repo.find_package(
diff --git a/crates/shirabe/src/command/bump_command.rs b/crates/shirabe/src/command/bump_command.rs
index a4518b0b..51a779ef 100644
--- a/crates/shirabe/src/command/bump_command.rs
+++ b/crates/shirabe/src/command/bump_command.rs
@@ -305,10 +305,10 @@ impl BumpCommand {
let contents = match file_get_contents(json.get_path()) {
Some(c) => c,
None => {
- return Err(shirabe_php_shim::RuntimeException {
- message: format!("Unable to read {} contents.", json.get_path()),
- code: 0,
- }
+ return Err(shirabe_php_shim::RuntimeException::new(format!(
+ "Unable to read {} contents.",
+ json.get_path()
+ ))
.into());
}
};
@@ -325,10 +325,10 @@ impl BumpCommand {
match file_put_contents(json.get_path(), manipulator.get_contents().as_bytes()) {
Some(_) => Ok(true),
- None => Err(shirabe_php_shim::RuntimeException {
- message: format!("Unable to write new {} contents.", json.get_path()),
- code: 0,
- }
+ None => Err(shirabe_php_shim::RuntimeException::new(format!(
+ "Unable to write new {} contents.",
+ json.get_path()
+ ))
.into()),
}
}
diff --git a/crates/shirabe/src/command/config_command.rs b/crates/shirabe/src/command/config_command.rs
index 2727f36b..3b976ba2 100644
--- a/crates/shirabe/src/command/config_command.rs
+++ b/crates/shirabe/src/command/config_command.rs
@@ -86,11 +86,10 @@ impl ConfigCommand {
) -> anyhow::Result<()> {
let (validator, normalizer) = callbacks;
if 1 != values.len() {
- return Err(RuntimeException {
- message: "You can only pass one value. Example: shirabe config process-timeout 300"
+ return Err(RuntimeException::new(
+ "You can only pass one value. Example: shirabe config process-timeout 300"
.to_string(),
- code: 0,
- }
+ )
.into());
}
@@ -101,10 +100,11 @@ impl ConfigCommand {
} else {
String::new()
};
- return Err(RuntimeException {
- message: format!("\"{}\" is an invalid value{}", values[0].clone(), suffix),
- code: 0,
- }
+ return Err(RuntimeException::new(format!(
+ "\"{}\" is an invalid value{}",
+ values[0].clone(),
+ suffix
+ ))
.into());
}
@@ -160,14 +160,11 @@ impl ConfigCommand {
} else {
String::new()
};
- return Err(RuntimeException {
- message: format!(
- "{} is an invalid value{}",
- PhpMixed::from(json_encode(&values_mixed).ok()),
- suffix
- ),
- code: 0,
- }
+ return Err(RuntimeException::new(format!(
+ "{} is an invalid value{}",
+ PhpMixed::from(json_encode(&values_mixed).ok()),
+ suffix
+ ))
.into());
}
@@ -679,10 +676,9 @@ impl Command for ConfigCommand {
.unwrap_or_default();
if !setting_values.is_empty() && input.borrow().get_option("unset")?.as_bool() == Some(true)
{
- return Err(RuntimeException {
- message: "You can not combine a setting value with --unset".to_string(),
- code: 0,
- }
+ return Err(RuntimeException::new(
+ "You can not combine a setting value with --unset".to_string(),
+ )
.into());
}
@@ -731,10 +727,10 @@ impl Command for ConfigCommand {
{
Some(v) => v.clone(),
None => {
- return Err(InvalidArgumentException {
- message: format!("There is no {} repository defined", repo_key),
- code: 0,
- }
+ return Err(InvalidArgumentException::new(format!(
+ "There is no {} repository defined",
+ repo_key
+ ))
.into());
}
};
@@ -766,11 +762,9 @@ impl Command for ConfigCommand {
}
if !r#match {
- return Err(RuntimeException {
- message: format!("{} is not defined.", setting_key),
- code: 0,
- }
- .into());
+ return Err(
+ RuntimeException::new(format!("{} is not defined.", setting_key)).into(),
+ );
}
value = cursor;
@@ -847,11 +841,9 @@ impl Command for ConfigCommand {
value = v.clone();
source = "defaults".to_string();
} else {
- return Err(RuntimeException {
- message: format!("{} is not defined", setting_key),
- code: 0,
- }
- .into());
+ return Err(
+ RuntimeException::new(format!("{} is not defined", setting_key)).into(),
+ );
}
let value_str = if is_array(&value) || is_object(&value) || is_bool(&value) {
@@ -961,13 +953,10 @@ impl Command for ConfigCommand {
.as_bool()
.unwrap_or(false)
{
- return Err(RuntimeException {
- message: format!(
- "Invalid value for {}. Should be one of: auto, source, or dist",
- setting_key
- ),
- code: 0,
- }
+ return Err(RuntimeException::new(format!(
+ "Invalid value for {}. Should be one of: auto, source, or dist",
+ setting_key
+ ))
.into());
}
@@ -998,10 +987,10 @@ impl Command for ConfigCommand {
}
if !boolean_validator(&PhpMixed::String(values[0].clone())) {
- return Err(RuntimeException {
- message: format!("\"{}\" is an invalid value", values[0].clone()),
- code: 0,
- }
+ return Err(RuntimeException::new(format!(
+ "\"{}\" is an invalid value",
+ values[0].clone()
+ ))
.into());
}
@@ -1025,10 +1014,7 @@ impl Command for ConfigCommand {
|| multi_props.contains_key(&setting_key)
|| strpos(&setting_key, "extra.") == Some(0))
{
- return Err(InvalidArgumentException {
- message: format!("The {} property can not be set in the global config.json file. Use `composer global config` to apply changes to the global composer.json", setting_key),
- code: 0,
- }
+ return Err(InvalidArgumentException::new(format!("The {} property can not be set in the global config.json file. Use `composer global config` to apply changes to the global composer.json", setting_key))
.into());
}
if input.borrow().get_option("unset")?.as_bool() == Some(true)
@@ -1122,10 +1108,7 @@ impl Command for ConfigCommand {
}
}
- return Err(RuntimeException {
- message: "You must pass the type and a url. Example: shirabe config repositories.foo vcs https://bar.com".to_string(),
- code: 0,
- }
+ return Err(RuntimeException::new("You must pass the type and a url. Example: shirabe config repositories.foo vcs https://bar.com".to_string())
.into());
}
@@ -1308,10 +1291,10 @@ impl Command for ConfigCommand {
if input.borrow().get_option("json")?.as_bool() == Some(true) {
value = JsonFile::parse_json(Some(&values[0]), Some("composer.json"))?;
if !is_array(&value) {
- return Err(RuntimeException {
- message: format!("Expected an array or object for {}", setting_key),
- code: 0,
- }
+ return Err(RuntimeException::new(format!(
+ "Expected an array or object for {}",
+ setting_key
+ ))
.into());
}
}
@@ -1349,10 +1332,10 @@ impl Command for ConfigCommand {
}
value = PhpMixed::Array(merged);
} else {
- return Err(RuntimeException {
- message: format!("Cannot merge array and object for {}", setting_key),
- code: 0,
- }
+ return Err(RuntimeException::new(format!(
+ "Cannot merge array and object for {}",
+ setting_key
+ ))
.into());
}
}
@@ -1394,13 +1377,10 @@ impl Command for ConfigCommand {
let key = format!("{}.{}", matches[1], matches[2]);
if matches[1] == "bitbucket-oauth" {
if 2 != values.len() {
- return Err(RuntimeException {
- message: format!(
- "Expected two arguments (consumer-key, consumer-secret), got {}",
- values.len()
- ),
- code: 0,
- }
+ return Err(RuntimeException::new(format!(
+ "Expected two arguments (consumer-key, consumer-secret), got {}",
+ values.len()
+ ))
.into());
}
self.config_source
@@ -1441,10 +1421,9 @@ impl Command for ConfigCommand {
"github-oauth" | "gitlab-oauth" | "gitlab-token" | "bearer"
) {
if 1 != values.len() {
- return Err(RuntimeException {
- message: "Too many arguments, expected only one token".to_string(),
- code: 0,
- }
+ return Err(RuntimeException::new(
+ "Too many arguments, expected only one token".to_string(),
+ )
.into());
}
self.config_source
@@ -1459,13 +1438,10 @@ impl Command for ConfigCommand {
.add_config_setting(&key, PhpMixed::String(values[0].clone()));
} else if matches[1] == "http-basic" {
if 2 != values.len() {
- return Err(RuntimeException {
- message: format!(
- "Expected two arguments (username, password), got {}",
- values.len()
- ),
- code: 0,
- }
+ return Err(RuntimeException::new(format!(
+ "Expected two arguments (username, password), got {}",
+ values.len()
+ ))
.into());
}
self.config_source
@@ -1483,10 +1459,9 @@ impl Command for ConfigCommand {
.add_config_setting(&key, PhpMixed::Array(obj));
} else if matches[1] == "custom-headers" {
if values.is_empty() {
- return Err(RuntimeException {
- message: "Expected at least one argument (header), got none".to_string(),
- code: 0,
- }
+ return Err(RuntimeException::new(
+ "Expected at least one argument (header), got none".to_string(),
+ )
.into());
}
@@ -1494,12 +1469,10 @@ impl Command for ConfigCommand {
let mut formatted_headers: Vec<PhpMixed> = vec![];
for header in &values {
if !is_string(&PhpMixed::String(header.clone())) {
- return Err(RuntimeException {
- message:
- "Headers must be strings in \"Header-Name: Header-Value\" format"
- .to_string(),
- code: 0,
- }
+ return Err(RuntimeException::new(
+ "Headers must be strings in \"Header-Name: Header-Value\" format"
+ .to_string(),
+ )
.into());
}
@@ -1510,13 +1483,10 @@ impl Command for ConfigCommand {
header,
Some(&mut header_parts),
) {
- return Err(RuntimeException {
- message: format!(
- "Header \"{}\" is not in \"Header-Name: Header-Value\" format",
- header
- ),
- code: 0,
- }
+ return Err(RuntimeException::new(format!(
+ "Header \"{}\" is not in \"Header-Name: Header-Value\" format",
+ header
+ ))
.into());
}
@@ -1535,13 +1505,10 @@ impl Command for ConfigCommand {
.add_config_setting(&key, PhpMixed::List(formatted_headers));
} else if matches[1] == "forgejo-token" {
if 2 != values.len() {
- return Err(RuntimeException {
- message: format!(
- "Expected two arguments (username, access token), got {}",
- values.len()
- ),
- code: 0,
- }
+ return Err(RuntimeException::new(format!(
+ "Expected two arguments (username, access token), got {}",
+ values.len()
+ ))
.into());
}
self.config_source
@@ -1604,13 +1571,10 @@ impl Command for ConfigCommand {
return Ok(0);
}
- Err(InvalidArgumentException {
- message: format!(
- "Setting {} does not exist or is not supported by this command",
- setting_key
- ),
- code: 0,
- }
+ Err(InvalidArgumentException::new(format!(
+ "Setting {} does not exist or is not supported by this command",
+ setting_key
+ ))
.into())
}
diff --git a/crates/shirabe/src/command/create_project_command.rs b/crates/shirabe/src/command/create_project_command.rs
index aa1b79a8..267c866e 100644
--- a/crates/shirabe/src/command/create_project_command.rs
+++ b/crates/shirabe/src/command/create_project_command.rs
@@ -42,6 +42,7 @@ use shirabe_external_packages::symfony::console::command::command::Command;
use shirabe_external_packages::symfony::console::input::InputInterface;
use shirabe_external_packages::symfony::console::output::OutputInterface;
use shirabe_external_packages::symfony::finder::Finder;
+use shirabe_php_shim::Catch as _;
use shirabe_php_shim::{
DIRECTORY_SEPARATOR, InvalidArgumentException, PhpMixed, RuntimeException,
UnexpectedValueException, array_pop, chdir, explode_with_limit, file_exists, getcwd,
@@ -311,7 +312,7 @@ impl CreateProjectCommand {
}
}
Err(e) => {
- if e.downcast_ref::<PluginBlockedException>().is_some() {
+ if e.is_instanceof::<PluginBlockedException>() {
io.write_error("<error>Hint: To allow running the config command recommended below before dependencies are installed, run create-project with --no-install.</error>");
io.write_error(&format!(
"<error>You can then cd into {}, configure allow-plugins, and finally run a composer install to complete the process.</error>",
@@ -365,11 +366,7 @@ impl CreateProjectCommand {
for dir in &dirs {
if !fs.remove_directory(dir)? {
had_error = Some(
- RuntimeException {
- message: format!("Could not remove {}", dir.display()),
- code: 0,
- }
- .into(),
+ RuntimeException::new(format!("Could not remove {}", dir.display())).into(),
);
break;
}
@@ -485,10 +482,9 @@ impl CreateProjectCommand {
);
}
if directory.is_empty() {
- return Err(UnexpectedValueException {
- message: "Got an empty target directory, something went wrong".to_string(),
- code: 0,
- }
+ return Err(UnexpectedValueException::new(
+ "Got an empty target directory, something went wrong".to_string(),
+ )
.into());
}
@@ -513,20 +509,17 @@ impl CreateProjectCommand {
if file_exists(&directory) {
if !is_dir(&directory) {
- return Err(InvalidArgumentException {
- message: format!(
- "Cannot create project directory at \"{}\", it exists as a file.",
- directory
- ),
- code: 0,
- }
+ return Err(InvalidArgumentException::new(format!(
+ "Cannot create project directory at \"{}\", it exists as a file.",
+ directory
+ ))
.into());
}
if !fs.borrow().is_dir_empty(&directory) {
- return Err(InvalidArgumentException {
- message: format!("Project directory \"{}\" is not empty.", directory),
- code: 0,
- }
+ return Err(InvalidArgumentException::new(format!(
+ "Project directory \"{}\" is not empty.",
+ directory
+ ))
.into());
}
}
@@ -575,20 +568,17 @@ impl CreateProjectCommand {
.unwrap_or_default();
if !STABILITIES.contains_key(stability.as_str()) {
- return Err(InvalidArgumentException {
- message: format!(
- "Invalid stability provided ({}), must be one of: {}",
- stability,
- implode(
- ", ",
- &STABILITIES
- .keys()
- .map(|k| k.to_string())
- .collect::<Vec<_>>()
- )
- ),
- code: 0,
- }
+ return Err(InvalidArgumentException::new(format!(
+ "Invalid stability provided ({}), must be one of: {}",
+ stability,
+ implode(
+ ", ",
+ &STABILITIES
+ .keys()
+ .map(|k| k.to_string())
+ .collect::<Vec<_>>()
+ )
+ ))
.into());
}
@@ -730,21 +720,14 @@ impl CreateProjectCommand {
)?
.is_some()
{
- return Err(InvalidArgumentException {
- message: format!(
- "{} in a version installable using your PHP version, PHP extensions and Composer version.",
- error_message
- ),
- code: 0,
- }
+ return Err(InvalidArgumentException::new(format!(
+ "{} in a version installable using your PHP version, PHP extensions and Composer version.",
+ error_message
+ ))
.into());
}
- return Err(InvalidArgumentException {
- message: format!("{}.", error_message),
- code: 0,
- }
- .into());
+ return Err(InvalidArgumentException::new(format!("{}.", error_message)).into());
}
let mut package = package.unwrap();
@@ -936,10 +919,9 @@ impl Command for CreateProjectCommand {
{
let package = input.borrow().get_argument("package")?;
if package.is_null() {
- return Err(RuntimeException {
- message: "Not enough arguments (missing: \"package\").".to_string(),
- code: 0,
- }
+ return Err(RuntimeException::new(
+ "Not enough arguments (missing: \"package\").".to_string(),
+ )
.into());
}
let mut parts =
diff --git a/crates/shirabe/src/command/diagnose_command.rs b/crates/shirabe/src/command/diagnose_command.rs
index 72b58dea..857e517d 100644
--- a/crates/shirabe/src/command/diagnose_command.rs
+++ b/crates/shirabe/src/command/diagnose_command.rs
@@ -38,11 +38,12 @@ use shirabe_external_packages::symfony::console::command::command::Command;
use shirabe_external_packages::symfony::console::input::InputInterface;
use shirabe_external_packages::symfony::console::output::OutputInterface;
use shirabe_external_packages::symfony::process::ExecutableFinder;
+use shirabe_php_shim::Catch as _;
use shirabe_php_shim::{
- CmpOp, InvalidArgumentException, PHP_EOL, PhpMixed, disk_free_space, file_exists,
- filter_var_boolean, get_class_err, hash, impl_php_class, implode, is_array, is_string,
- php_regex, rtrim, str_contains, str_replace, str_starts_with, strpos, strstr, strstr3,
- strtolower, trim, version_compare,
+ AnyThrowable, CmpOp, InvalidArgumentException, PHP_EOL, PhpClass as _, PhpMixed,
+ disk_free_space, file_exists, filter_var_boolean, hash, impl_php_class, implode, is_array,
+ is_string, php_regex, rtrim, str_contains, str_replace, str_starts_with, strpos, strstr,
+ strstr3, strtolower, trim, version_compare,
};
#[derive(Debug)]
@@ -106,7 +107,7 @@ impl DiagnoseCommand {
match json.validate_schema(JsonFile::LOCK_SCHEMA, None) {
Ok(_) => {}
Err(e) => {
- if let Some(jve) = e.downcast_ref::<JsonValidationException>() {
+ if let Some(jve) = e.catch::<JsonValidationException>() {
let mut output = String::new();
for error in jve.get_errors() {
output.push_str(&format!("<error>{}</error>{}", error, PHP_EOL));
@@ -191,7 +192,7 @@ impl DiagnoseCommand {
) {
Ok(_) => {}
Err(e) => {
- if let Some(te) = e.downcast_ref::<TransportException>() {
+ if let Some(te) = e.catch::<TransportException>() {
let hints = HttpDownloader::get_exception_hints(&e).unwrap_or_default();
if !hints.is_empty() {
for hint in hints {
@@ -202,7 +203,7 @@ impl DiagnoseCommand {
result_list.push(PhpMixed::String(format!(
"<error>[{}] {}</error>",
std::any::type_name_of_val(te),
- te.message
+ te.get_message()
)));
} else {
return Err(e);
@@ -249,7 +250,7 @@ impl DiagnoseCommand {
{
Ok(_) => {}
Err(e) => {
- if let Some(te) = e.downcast_ref::<TransportException>() {
+ if let Some(te) = e.catch::<TransportException>() {
let hints = HttpDownloader::get_exception_hints(&e).unwrap_or_default();
if !hints.is_empty() {
for hint in hints {
@@ -260,7 +261,7 @@ impl DiagnoseCommand {
result_list.push(PhpMixed::String(format!(
"<error>[{}] {}</error>",
std::any::type_name_of_val(te),
- te.message
+ te.get_message()
)));
} else {
return Err(e);
@@ -394,7 +395,7 @@ impl DiagnoseCommand {
)))
}
Err(e) => {
- if let Some(te) = e.downcast_ref::<TransportException>()
+ if let Some(te) = e.catch::<TransportException>()
&& te.get_code() == 401
{
return Ok(PhpMixed::String(format!(
@@ -404,7 +405,9 @@ impl DiagnoseCommand {
}
Ok(PhpMixed::String(format!(
"<error>[{}] {}</error>",
- get_class_err(&e),
+ AnyThrowable::of(e.as_ref())
+ .expect("PHP reaches this only with a caught \\Throwable")
+ .php_class_name(),
e
)))
}
@@ -540,13 +543,16 @@ impl DiagnoseCommand {
Ok(Err(e)) => {
return Ok(PhpMixed::String(format!(
"<error>[{}] {}</error>",
- "UnexpectedValueException", e.message
+ "UnexpectedValueException",
+ e.get_message()
)));
}
Err(e) => {
return Ok(PhpMixed::String(format!(
"<error>[{}] {}</error>",
- get_class_err(&e),
+ AnyThrowable::of(e.as_ref())
+ .expect("PHP reaches this only with a caught \\Throwable")
+ .php_class_name(),
e
)));
}
@@ -960,13 +966,10 @@ impl DiagnoseCommand {
PHP_EOL, PHP_EOL
),
other => {
- return Err(InvalidArgumentException {
- message: format!(
- "DiagnoseCommand: Unknown error type \"{}\". Please report at https://github.com/composer/composer/issues/new.",
- other,
- ),
- code: 0,
- }
+ return Err(InvalidArgumentException::new(format!(
+ "DiagnoseCommand: Unknown error type \"{}\". Please report at https://github.com/composer/composer/issues/new.",
+ other,
+ ))
.into());
}
};
@@ -1042,13 +1045,10 @@ impl DiagnoseCommand {
PHP_EOL
),
other => {
- return Err(InvalidArgumentException {
- message: format!(
- "DiagnoseCommand: Unknown warning type \"{}\". Please report at https://github.com/composer/composer/issues/new.",
- other,
- ),
- code: 0,
- }
+ return Err(InvalidArgumentException::new(format!(
+ "DiagnoseCommand: Unknown warning type \"{}\". Please report at https://github.com/composer/composer/issues/new.",
+ other,
+ ))
.into());
}
};
@@ -1409,13 +1409,19 @@ impl Command for DiagnoseCommand {
Ok(())
})();
if let Err(e) = proxy_check_result {
- if let Some(_te) = e.downcast_ref::<TransportException>() {
+ if let Some(_te) = e.catch::<TransportException>() {
io.write_no_newline("Checking HTTP proxy: ");
let status = self.check_connectivity_and_composer_network_http_enablement();
self.output_result(if is_string(&status) {
status
} else {
- PhpMixed::String(format!("<error>[{}] {}</error>", get_class_err(&e), e))
+ PhpMixed::String(format!(
+ "<error>[{}] {}</error>",
+ AnyThrowable::of(e.as_ref())
+ .expect("PHP reaches this only with a caught \\Throwable")
+ .php_class_name(),
+ e
+ ))
});
} else {
return Err(e);
@@ -1455,20 +1461,24 @@ impl Command for DiagnoseCommand {
}
}
Err(e) => {
- if let Some(te) = e.downcast_ref::<TransportException>() {
+ if let Some(te) = e.catch::<TransportException>() {
if te.get_code() == 401 {
self.output_result(PhpMixed::String("<comment>The oauth token for github.com seems invalid, run \"composer config --global --unset github-oauth.github.com\" to remove it</comment>".to_string()));
} else {
self.output_result(PhpMixed::String(format!(
"<error>[{}] {}</error>",
- get_class_err(&e),
+ AnyThrowable::of(e.as_ref())
+ .expect("PHP reaches this only with a caught \\Throwable")
+ .php_class_name(),
e
)));
}
} else {
self.output_result(PhpMixed::String(format!(
"<error>[{}] {}</error>",
- get_class_err(&e),
+ AnyThrowable::of(e.as_ref())
+ .expect("PHP reaches this only with a caught \\Throwable")
+ .php_class_name(),
e
)));
}
diff --git a/crates/shirabe/src/command/dump_autoload_command.rs b/crates/shirabe/src/command/dump_autoload_command.rs
index 8aad0705..f9be4cff 100644
--- a/crates/shirabe/src/command/dump_autoload_command.rs
+++ b/crates/shirabe/src/command/dump_autoload_command.rs
@@ -149,10 +149,7 @@ impl Command for DumpAutoloadCommand {
&& !optimize
&& !authoritative
{
- return Err(InvalidArgumentException {
- message: "--strict-psr mode only works with optimized autoloader, use --optimize or --classmap-authoritative if you want a strict return value.".to_string(),
- code: 0,
- }
+ return Err(InvalidArgumentException::new("--strict-psr mode only works with optimized autoloader, use --optimize or --classmap-authoritative if you want a strict return value.".to_string())
.into());
}
if input
@@ -163,10 +160,7 @@ impl Command for DumpAutoloadCommand {
&& !optimize
&& !authoritative
{
- return Err(InvalidArgumentException {
- message: "--strict-ambiguous mode only works with optimized autoloader, use --optimize or --classmap-authoritative if you want a strict return value.".to_string(),
- code: 0,
- }
+ return Err(InvalidArgumentException::new("--strict-ambiguous mode only works with optimized autoloader, use --optimize or --classmap-authoritative if you want a strict return value.".to_string())
.into());
}
@@ -208,12 +202,10 @@ impl Command for DumpAutoloadCommand {
.as_bool()
.unwrap_or(false)
{
- return Err(InvalidArgumentException {
- message:
- "You can not use both --no-dev and --dev as they conflict with each other."
- .to_string(),
- code: 0,
- }
+ return Err(InvalidArgumentException::new(
+ "You can not use both --no-dev and --dev as they conflict with each other."
+ .to_string(),
+ )
.into());
}
composer
diff --git a/crates/shirabe/src/command/exec_command.rs b/crates/shirabe/src/command/exec_command.rs
index d05b6c58..a67c234e 100644
--- a/crates/shirabe/src/command/exec_command.rs
+++ b/crates/shirabe/src/command/exec_command.rs
@@ -174,13 +174,10 @@ impl Command for ExecCommand {
.as_string()
.unwrap_or("")
.to_string();
- return Err(RuntimeException {
- message: format!(
- "No binaries found in composer.json or in bin-dir ({})",
- bin_dir
- ),
- code: 0,
- }
+ return Err(RuntimeException::new(format!(
+ "No binaries found in composer.json or in bin-dir ({})",
+ bin_dir
+ ))
.into());
}
@@ -222,9 +219,11 @@ impl Command for ExecCommand {
if let Some(ref iwd) = initial_working_directory
&& getcwd().as_deref() != Some(iwd.as_str())
{
- chdir(iwd).map_err(|e| RuntimeException {
- message: format!("Could not switch back to working directory \"{}\"", iwd),
- code: 0,
+ chdir(iwd).map_err(|e| {
+ RuntimeException::new(format!(
+ "Could not switch back to working directory \"{}\"",
+ iwd
+ ))
})?;
}
diff --git a/crates/shirabe/src/command/global_command.rs b/crates/shirabe/src/command/global_command.rs
index 79037e55..78b6f3e6 100644
--- a/crates/shirabe/src/command/global_command.rs
+++ b/crates/shirabe/src/command/global_command.rs
@@ -61,11 +61,10 @@ impl GlobalCommand {
} else if let Some(completion_input) = input_any.downcast_ref::<CompletionInput>() {
Ok(completion_input.to_string())
} else {
- Err(LogicException {
- message: "Expected an Input instance that is stringable".to_string(),
- code: 0,
- }
- .into())
+ Err(
+ LogicException::new("Expected an Input instance that is stringable".to_string())
+ .into(),
+ )
}
}
@@ -85,17 +84,14 @@ impl GlobalCommand {
let mut fs = Filesystem::new(None);
fs.ensure_directory_exists(&home)?;
if !Path::new(&home).is_dir() {
- return Err(RuntimeException {
- message: "Could not create home directory".to_string(),
- code: 0,
- }
- .into());
+ return Err(
+ RuntimeException::new("Could not create home directory".to_string()).into(),
+ );
}
}
- chdir(&home).map_err(|_e| RuntimeException {
- message: format!("Could not switch to home directory \"{}\"", home),
- code: 0,
+ chdir(&home).map_err(|_e| {
+ RuntimeException::new(format!("Could not switch to home directory \"{}\"", home))
})?;
if !quiet {
diff --git a/crates/shirabe/src/command/init_command.rs b/crates/shirabe/src/command/init_command.rs
index 5168b2ba..7b4012ce 100644
--- a/crates/shirabe/src/command/init_command.rs
+++ b/crates/shirabe/src/command/init_command.rs
@@ -25,6 +25,7 @@ use shirabe_external_packages::symfony::console::helper::FormatBlockMessages;
use shirabe_external_packages::symfony::console::input::ArrayInput;
use shirabe_external_packages::symfony::console::input::InputInterface;
use shirabe_external_packages::symfony::console::output::OutputInterface;
+use shirabe_php_shim::Catch as _;
use shirabe_php_shim::{
FILE_IGNORE_NEW_LINES, InvalidArgumentException, PHP_EOL, PHP_SERVER, PhpMixed,
array_flip_strings, array_intersect_key, array_map, basename, empty, explode, file,
@@ -99,11 +100,9 @@ impl InitCommand {
if let Some(ref email) = email
&& !self.is_valid_email(email)
{
- return Err(InvalidArgumentException {
- message: format!("Invalid email \"{}\"", email),
- code: 0,
- }
- .into());
+ return Err(
+ InvalidArgumentException::new(format!("Invalid email \"{}\"", email)).into(),
+ );
}
let mut result: IndexMap<String, Option<String>> = IndexMap::new();
@@ -121,11 +120,8 @@ impl InitCommand {
return Ok(result);
}
- Err(InvalidArgumentException {
- message: "Invalid author string. Must be in the formats: Jane Doe or John Smith <john@example.com>"
- .to_string(),
- code: 0,
- }
+ Err(InvalidArgumentException::new("Invalid author string. Must be in the formats: Jane Doe or John Smith <john@example.com>"
+ .to_string())
.into())
}
@@ -517,13 +513,10 @@ impl Command for InitCommand {
.unwrap_or(""),
)
{
- return Err(InvalidArgumentException {
- message: format!(
- "The package name {} is invalid, it should be lowercase and have a vendor name, a forward slash, and a package name, matching: [a-z0-9_.-]+/[a-z0-9_.-]+",
- options.get("name").and_then(|v| v.as_string()).unwrap_or("")
- ),
- code: 0,
- }
+ return Err(InvalidArgumentException::new(format!(
+ "The package name {} is invalid, it should be lowercase and have a vendor name, a forward slash, and a package name, matching: [a-z0-9_.-]+/[a-z0-9_.-]+",
+ options.get("name").and_then(|v| v.as_string()).unwrap_or("")
+ ))
.into());
}
@@ -678,7 +671,7 @@ impl Command for InitCommand {
let validate_result = file_obj.validate_schema(JsonFile::LAX_SCHEMA, None);
if let Err(e) = validate_result {
// try to downcast to JsonValidationException
- if let Some(json_err) = e.downcast_ref::<JsonValidationException>() {
+ if let Some(json_err) = e.catch::<JsonValidationException>() {
io.write_error3(
"<error>Schema validation error, aborting</error>",
true,
@@ -926,13 +919,10 @@ impl Command for InitCommand {
php_regex!(r"{^[a-z0-9]([_.-]?[a-z0-9]+)*\/[a-z0-9](([_.]|-{1,2})?[a-z0-9]+)*$}D"),
value.as_string().unwrap_or(""),
) {
- return Err(InvalidArgumentException {
- message: format!(
- "The package name {} is invalid, it should be lowercase and have a vendor name, a forward slash, and a package name, matching: [a-z0-9_.-]+/[a-z0-9_.-]+",
- value.as_string().unwrap_or("")
- ),
- code: 0,
- }
+ return Err(InvalidArgumentException::new(format!(
+ "The package name {} is invalid, it should be lowercase and have a vendor name, a forward slash, and a package name, matching: [a-z0-9_.-]+/[a-z0-9_.-]+",
+ value.as_string().unwrap_or("")
+ ))
.into());
}
@@ -1031,20 +1021,17 @@ impl Command for InitCommand {
}
if !base_package::STABILITIES.contains_key(value.as_string().unwrap_or("")) {
- return Err(InvalidArgumentException {
- message: format!(
- "Invalid minimum stability \"{}\". Must be empty or one of: {}",
- value.as_string().unwrap_or(""),
- implode(
- ", ",
- &base_package::STABILITIES
- .keys()
- .map(|k| k.to_string())
- .collect::<Vec<_>>()
- )
- ),
- code: 0,
- }
+ return Err(InvalidArgumentException::new(format!(
+ "Invalid minimum stability \"{}\". Must be empty or one of: {}",
+ value.as_string().unwrap_or(""),
+ implode(
+ ", ",
+ &base_package::STABILITIES
+ .keys()
+ .map(|k| k.to_string())
+ .collect::<Vec<_>>()
+ )
+ ))
.into());
}
@@ -1107,13 +1094,10 @@ impl Command for InitCommand {
&& !spdx.validate(license.as_string().unwrap_or(""))
&& license.as_string() != Some("proprietary")
{
- return Err(InvalidArgumentException {
- message: format!(
+ return Err(InvalidArgumentException::new(format!(
"Invalid license provided: {}. Only SPDX license identifiers (https://spdx.org/licenses/) or \"proprietary\" are accepted.",
license.as_string().unwrap_or("")
- ),
- code: 0,
- }
+ ))
.into());
}
input.borrow_mut().set_option("license", license);
@@ -1246,13 +1230,10 @@ impl Command for InitCommand {
if !Preg::is_match(php_regex!(r"{^[^/][A-Za-z0-9\-_/]+/$}"), &value_or_default)
{
- return Err(InvalidArgumentException {
- message: format!(
- "The src folder name \"{}\" is invalid. Please add a relative path with tailing forward slash. [A-Za-z0-9_-/]+/",
- value_or_default,
- ),
- code: 0,
- }
+ return Err(InvalidArgumentException::new(format!(
+ "The src folder name \"{}\" is invalid. Please add a relative path with tailing forward slash. [A-Za-z0-9_-/]+/",
+ value_or_default,
+ ))
.into());
}
diff --git a/crates/shirabe/src/command/licenses_command.rs b/crates/shirabe/src/command/licenses_command.rs
index 41e9ba90..1b2ec6b6 100644
--- a/crates/shirabe/src/command/licenses_command.rs
+++ b/crates/shirabe/src/command/licenses_command.rs
@@ -128,10 +128,7 @@ impl Command for LicensesCommand {
let locker = composer.get_locker().clone();
let mut locker = locker.borrow_mut();
if !locker.is_locked() {
- return Err(UnexpectedValueException {
- message: "Valid composer.json and composer.lock files are required to run this command with --locked".to_string(),
- code: 0,
- }.into());
+ return Err(UnexpectedValueException::new("Valid composer.json and composer.lock files are required to run this command with --locked".to_string()).into());
}
let no_dev = input
.borrow()
@@ -314,13 +311,10 @@ impl Command for LicensesCommand {
);
}
_ => {
- return Err(RuntimeException {
- message: format!(
- "Unsupported format \"{}\". See help for supported formats.",
- format
- ),
- code: 0,
- }
+ return Err(RuntimeException::new(format!(
+ "Unsupported format \"{}\". See help for supported formats.",
+ format
+ ))
.into());
}
}
diff --git a/crates/shirabe/src/command/package_discovery_trait.rs b/crates/shirabe/src/command/package_discovery_trait.rs
index db7db488..17332083 100644
--- a/crates/shirabe/src/command/package_discovery_trait.rs
+++ b/crates/shirabe/src/command/package_discovery_trait.rs
@@ -22,6 +22,7 @@ use indexmap::IndexMap;
use shirabe_external_packages::composer::pcre::{CaptureKey, Preg};
use shirabe_external_packages::symfony::console::input::InputInterface;
use shirabe_external_packages::symfony::console::output::OutputInterface;
+use shirabe_php_shim::Catch as _;
use shirabe_php_shim::{
Exception, InvalidArgumentException, LogicException, PHP_EOL, PhpMixed, array_keys,
array_slice, asort, explode, file_get_contents, implode, in_array_strict, is_array, is_file,
@@ -359,11 +360,7 @@ pub trait PackageDiscoveryTrait: BaseCommand {
));
}
- Err(Exception {
- message: "Not a valid selection".to_string(),
- code: 0,
- }
- .into())
+ Err(Exception::new("Not a valid selection".to_string()).into())
},
);
@@ -541,17 +538,14 @@ pub trait PackageDiscoveryTrait: BaseCommand {
ShowWarnings::Always,
)?;
if let Some(candidate) = candidate {
- return Err(InvalidArgumentException {
- message: format!(
- "Package {} has requirements incompatible with your PHP version, PHP extensions and Composer version{}",
- name,
- self.get_platform_exception_details(
- candidate,
- platform_repo,
- )?,
- ),
- code: 0,
- }
+ return Err(InvalidArgumentException::new(format!(
+ "Package {} has requirements incompatible with your PHP version, PHP extensions and Composer version{}",
+ name,
+ self.get_platform_exception_details(
+ candidate,
+ platform_repo,
+ )?,
+ ))
.into());
}
}
@@ -577,34 +571,28 @@ pub trait PackageDiscoveryTrait: BaseCommand {
ShowWarnings::Always,
)?;
if let Some(all_repos_package) = all_repos_package {
- return Err(InvalidArgumentException {
- message: format!(
- "Package {} exists in {} and {} which has a higher repository priority. The packages from the higher priority repository do not match your minimum-stability and are therefore not installable. That repository is canonical so the lower priority repo's packages are not installable. See https://getcomposer.org/repoprio for details and assistance.",
- name,
- all_repos_package
- .get_repository()
- .map(|r| r.get_repo_name())
- .transpose()?
- .unwrap_or_default(),
- package
- .get_repository()
- .map(|r| r.get_repo_name())
- .transpose()?
- .unwrap_or_default(),
- ),
- code: 0,
- }
+ return Err(InvalidArgumentException::new(format!(
+ "Package {} exists in {} and {} which has a higher repository priority. The packages from the higher priority repository do not match your minimum-stability and are therefore not installable. That repository is canonical so the lower priority repo's packages are not installable. See https://getcomposer.org/repoprio for details and assistance.",
+ name,
+ all_repos_package
+ .get_repository()
+ .map(|r| r.get_repo_name())
+ .transpose()?
+ .unwrap_or_default(),
+ package
+ .get_repository()
+ .map(|r| r.get_repo_name())
+ .transpose()?
+ .unwrap_or_default(),
+ ))
.into());
}
- return Err(InvalidArgumentException {
- message: format!(
- "Could not find a version of package {} matching your minimum-stability ({}). Require it with an explicit version constraint allowing its desired stability.",
- name,
- effective_minimum_stability,
- ),
- code: 0,
- }
+ return Err(InvalidArgumentException::new(format!(
+ "Could not find a version of package {} matching your minimum-stability ({}). Require it with an explicit version constraint allowing its desired stability.",
+ name,
+ effective_minimum_stability,
+ ))
.into());
}
// Check whether the PHP version was the problem for all versions
@@ -639,18 +627,15 @@ pub trait PackageDiscoveryTrait: BaseCommand {
);
}
- return Err(InvalidArgumentException {
- message: format!(
- "Could not find package {} in any version matching your PHP version, PHP extensions and Composer version{}{}",
- name,
- self.get_platform_exception_details(
- candidate,
- platform_repo,
- )?,
- additional,
- ),
- code: 0,
- }
+ return Err(InvalidArgumentException::new(format!(
+ "Could not find package {} in any version matching your PHP version, PHP extensions and Composer version{}{}",
+ name,
+ self.get_platform_exception_details(
+ candidate,
+ platform_repo,
+ )?,
+ additional,
+ ))
.into());
}
}
@@ -665,13 +650,10 @@ pub trait PackageDiscoveryTrait: BaseCommand {
.map(|s| PhpMixed::String(s.clone()))
.collect::<Vec<_>>(),
) {
- return Err(InvalidArgumentException {
- message: format!(
- "Could not find package {}. It was however found via repository search, which indicates a consistency issue with the repository.",
- name,
- ),
- code: 0,
- }
+ return Err(InvalidArgumentException::new(format!(
+ "Could not find package {}. It was however found via repository search, which indicates a consistency issue with the repository.",
+ name,
+ ))
.into());
}
@@ -704,30 +686,24 @@ pub trait PackageDiscoveryTrait: BaseCommand {
}
}
- return Err(InvalidArgumentException {
- message: format!(
- "Could not find package {}.\n\nDid you mean {}?\n {}",
- name,
- if similar.len() > 1 {
- "one of these"
- } else {
- "this"
- },
- implode("\n ", &similar),
- ),
- code: 0,
- }
+ return Err(InvalidArgumentException::new(format!(
+ "Could not find package {}.\n\nDid you mean {}?\n {}",
+ name,
+ if similar.len() > 1 {
+ "one of these"
+ } else {
+ "this"
+ },
+ implode("\n ", &similar),
+ ))
.into());
}
- return Err(InvalidArgumentException {
- message: format!(
- "Could not find a matching version of package {}. Check the package spelling, your version constraint and that the package is available in a stability which matches your minimum-stability ({}).",
- name,
- effective_minimum_stability,
- ),
- code: 0,
- }
+ return Err(InvalidArgumentException::new(format!(
+ "Could not find a matching version of package {}. Check the package spelling, your version constraint and that the package is available in a stability which matches your minimum-stability ({}).",
+ name,
+ effective_minimum_stability,
+ ))
.into());
}
@@ -745,11 +721,9 @@ pub trait PackageDiscoveryTrait: BaseCommand {
fn find_similar(&self, package: &str) -> anyhow::Result<Vec<String>> {
let results: Vec<SearchResult> = match (|| -> anyhow::Result<Vec<SearchResult>> {
if self.get_repos_mut().is_none() {
- return Err(LogicException {
- message: "findSimilar was called before $this->repos was initialized"
- .to_string(),
- code: 0,
- }
+ return Err(LogicException::new(
+ "findSimilar was called before $this->repos was initialized".to_string(),
+ )
.into());
}
self.get_repos_mut()
@@ -760,7 +734,7 @@ pub trait PackageDiscoveryTrait: BaseCommand {
Ok(r) => r,
Err(e) => {
// PHP: if ($e instanceof \LogicException) throw $e;
- if e.downcast_ref::<LogicException>().is_some() {
+ if e.is_instanceof::<LogicException>() {
return Err(e);
}
diff --git a/crates/shirabe/src/command/reinstall_command.rs b/crates/shirabe/src/command/reinstall_command.rs
index b16b6c92..f9753f2a 100644
--- a/crates/shirabe/src/command/reinstall_command.rs
+++ b/crates/shirabe/src/command/reinstall_command.rs
@@ -98,12 +98,10 @@ impl Command for ReinstallCommand {
if type_count > 0 {
if packages_count > 0 {
- return Err(InvalidArgumentException {
- message:
- "You cannot specify package names and filter by type at the same time."
- .to_string(),
- code: 0,
- }
+ return Err(InvalidArgumentException::new(
+ "You cannot specify package names and filter by type at the same time."
+ .to_string(),
+ )
.into());
}
let filter_types: Vec<String> = type_option
@@ -122,11 +120,9 @@ impl Command for ReinstallCommand {
}
} else {
if packages_count == 0 {
- return Err(InvalidArgumentException {
- message: "You must pass one or more package names to be reinstalled."
- .to_string(),
- code: 0,
- }
+ return Err(InvalidArgumentException::new(
+ "You must pass one or more package names to be reinstalled.".to_string(),
+ )
.into());
}
let patterns: Vec<String> = packages_arg
diff --git a/crates/shirabe/src/command/remove_command.rs b/crates/shirabe/src/command/remove_command.rs
index 77deaf14..e89e9535 100644
--- a/crates/shirabe/src/command/remove_command.rs
+++ b/crates/shirabe/src/command/remove_command.rs
@@ -193,12 +193,10 @@ impl Command for RemoveCommand {
.as_bool()
.unwrap_or(false)
{
- return Err(anyhow::anyhow!(InvalidArgumentException(
- shirabe_php_shim::InvalidArgumentException {
- message: "Not enough arguments (missing: \"packages\").".to_string(),
- code: 0,
- }
- )));
+ return Err(InvalidArgumentException::new(
+ "Not enough arguments (missing: \"packages\").".to_string(),
+ )
+ .into());
}
let mut packages: Vec<String> = input
@@ -224,12 +222,11 @@ impl Command for RemoveCommand {
let locker = composer.get_locker().clone();
let mut locker = locker.borrow_mut();
if !locker.is_locked() {
- return Err(anyhow::anyhow!(UnexpectedValueException {
- message:
- "A valid composer.lock file is required to run this command with --unused"
- .to_string(),
- code: 0,
- }));
+ return Err(UnexpectedValueException::new(
+ "A valid composer.lock file is required to run this command with --unused"
+ .to_string(),
+ )
+ .into());
}
}
diff --git a/crates/shirabe/src/command/repository_command.rs b/crates/shirabe/src/command/repository_command.rs
index ab2cf2d4..47fd2d28 100644
--- a/crates/shirabe/src/command/repository_command.rs
+++ b/crates/shirabe/src/command/repository_command.rs
@@ -362,26 +362,20 @@ impl Command for RepositoryCommand {
}
"add" => {
if name.is_none() {
- return Err(anyhow::anyhow!(RuntimeException {
- message: "You must pass a repository name. Example: composer repo add foo vcs https://example.org".to_string(),
- code: 0,
- }));
+ return Err(RuntimeException::new("You must pass a repository name. Example: composer repo add foo vcs https://example.org".to_string()).into());
}
if arg1.is_none() {
- return Err(anyhow::anyhow!(RuntimeException {
- message: "You must pass the type and a url, or a JSON string.".to_string(),
- code: 0,
- }));
+ return Err(RuntimeException::new(
+ "You must pass the type and a url, or a JSON string.".to_string(),
+ )
+ .into());
}
let arg1_str = arg1.as_deref().unwrap();
let repo_config: PhpMixed = if Preg::is_match(php_regex!(r"{^\s*\{}"), arg1_str) {
JsonFile::parse_json(Some(arg1_str), None)?
} else {
if arg2.is_none() {
- return Err(anyhow::anyhow!(RuntimeException {
- message: "You must pass the type and a url. Example: composer repo add foo vcs https://example.org".to_string(),
- code: 0,
- }));
+ return Err(RuntimeException::new("You must pass the type and a url. Example: composer repo add foo vcs https://example.org".to_string()).into());
}
let mut m = IndexMap::new();
m.insert("type".to_string(), PhpMixed::String(arg1_str.to_string()));
@@ -400,19 +394,19 @@ impl Command for RepositoryCommand {
.as_string()
.map(|s| s.to_string());
if before.is_some() && after.is_some() {
- return Err(anyhow::anyhow!(RuntimeException {
- message: "You can not combine --before and --after".to_string(),
- code: 0,
- }));
+ return Err(RuntimeException::new(
+ "You can not combine --before and --after".to_string(),
+ )
+ .into());
}
if before.is_some() || after.is_some() {
if matches!(repo_config, PhpMixed::Bool(false)) {
- return Err(anyhow::anyhow!(RuntimeException {
- message: "Cannot use --before/--after with boolean repository values"
+ return Err(RuntimeException::new(
+ "Cannot use --before/--after with boolean repository values"
.to_string(),
- code: 0,
- }));
+ )
+ .into());
}
let reference_name = before.as_deref().or(after.as_deref()).unwrap();
let offset: i64 = if after.is_some() { 1 } else { 0 };
@@ -443,10 +437,10 @@ impl Command for RepositoryCommand {
}
"remove" | "rm" | "delete" => {
if name.is_none() {
- return Err(anyhow::anyhow!(RuntimeException {
- message: "You must pass the repository name to remove.".to_string(),
- code: 0,
- }));
+ return Err(RuntimeException::new(
+ "You must pass the repository name to remove.".to_string(),
+ )
+ .into());
}
let name_str = name.as_deref().unwrap();
self.config_source
@@ -465,10 +459,10 @@ impl Command for RepositoryCommand {
}
"set-url" | "seturl" => {
if name.is_none() || arg1.is_none() {
- return Err(anyhow::anyhow!(RuntimeException {
- message: "Usage: composer repo set-url <name> <new-url>".to_string(),
- code: 0,
- }));
+ return Err(RuntimeException::new(
+ "Usage: composer repo set-url <name> <new-url>".to_string(),
+ )
+ .into());
}
self.config_source
.borrow_mut()
@@ -479,10 +473,10 @@ impl Command for RepositoryCommand {
}
"get-url" | "geturl" => {
if name.is_none() {
- return Err(anyhow::anyhow!(RuntimeException {
- message: "Usage: composer repo get-url <name>".to_string(),
- code: 0,
- }));
+ return Err(RuntimeException::new(
+ "Usage: composer repo get-url <name>".to_string(),
+ )
+ .into());
}
let name_str = name.as_deref().unwrap();
if let Some(repo) = repos.get(name_str)
@@ -493,10 +487,11 @@ impl Command for RepositoryCommand {
self.get_io().write(url);
return Ok(0);
}
- return Err(anyhow::anyhow!(InvalidArgumentException {
- message: format!("The {} repository does not have a URL", name_str),
- code: 0,
- }));
+ return Err(InvalidArgumentException::new(format!(
+ "The {} repository does not have a URL",
+ name_str
+ ))
+ .into());
}
for (_key, val) in &repos {
if let PhpMixed::Array(ref repo_map) = *val
@@ -508,23 +503,25 @@ impl Command for RepositoryCommand {
self.get_io().write(url);
return Ok(0);
}
- return Err(anyhow::anyhow!(InvalidArgumentException {
- message: format!("The {} repository does not have a URL", name_str),
- code: 0,
- }));
+ return Err(InvalidArgumentException::new(format!(
+ "The {} repository does not have a URL",
+ name_str
+ ))
+ .into());
}
}
- Err(anyhow::anyhow!(InvalidArgumentException {
- message: format!("There is no {} repository defined", name_str),
- code: 0,
- }))
+ Err(InvalidArgumentException::new(format!(
+ "There is no {} repository defined",
+ name_str
+ ))
+ .into())
}
"disable" => {
if name.is_none() {
- return Err(anyhow::anyhow!(RuntimeException {
- message: "Usage: composer repo disable packagist.org".to_string(),
- code: 0,
- }));
+ return Err(RuntimeException::new(
+ "Usage: composer repo disable packagist.org".to_string(),
+ )
+ .into());
}
let name_str = name.as_deref().unwrap();
if ["packagist", "packagist.org"].contains(&name_str) {
@@ -540,17 +537,14 @@ impl Command for RepositoryCommand {
.add_repository("packagist.org", PhpMixed::Bool(false), append);
return Ok(0);
}
- Err(anyhow::anyhow!(RuntimeException {
- message: "Only packagist.org can be enabled/disabled using this command. Use add/remove for other repositories.".to_string(),
- code: 0,
- }))
+ Err(RuntimeException::new("Only packagist.org can be enabled/disabled using this command. Use add/remove for other repositories.".to_string()).into())
}
"enable" => {
if name.is_none() {
- return Err(anyhow::anyhow!(RuntimeException {
- message: "Usage: composer repo enable packagist.org".to_string(),
- code: 0,
- }));
+ return Err(RuntimeException::new(
+ "Usage: composer repo enable packagist.org".to_string(),
+ )
+ .into());
}
let name_str = name.as_deref().unwrap();
if ["packagist", "packagist.org"].contains(&name_str) {
@@ -561,19 +555,16 @@ impl Command for RepositoryCommand {
.remove_repository("packagist.org");
return Ok(0);
}
- Err(anyhow::anyhow!(RuntimeException {
- message: "Only packagist.org can be enabled/disabled using this command."
- .to_string(),
- code: 0,
- }))
+ Err(RuntimeException::new(
+ "Only packagist.org can be enabled/disabled using this command.".to_string(),
+ )
+ .into())
}
- _ => Err(anyhow::anyhow!(InvalidArgumentException {
- message: format!(
- "Unknown action \"{}\". Use list, add, remove, set-url, get-url, enable, disable",
- action
- ),
- code: 0,
- })),
+ _ => Err(InvalidArgumentException::new(format!(
+ "Unknown action \"{}\". Use list, add, remove, set-url, get-url, enable, disable",
+ action
+ ))
+ .into()),
}
}
diff --git a/crates/shirabe/src/command/require_command.rs b/crates/shirabe/src/command/require_command.rs
index 85e53a37..84b4a6e4 100644
--- a/crates/shirabe/src/command/require_command.rs
+++ b/crates/shirabe/src/command/require_command.rs
@@ -977,13 +977,10 @@ impl Command for RequireCommand {
if self.newly_created.get() {
self.revert_composer_file();
- return Err(RuntimeException {
- message: format!(
- "No composer.json present in the current directory ({}), this may be the cause of the following exception.",
- self.file.borrow()
- ),
- code: 0,
- }
+ return Err(RuntimeException::new(format!(
+ "No composer.json present in the current directory ({}), this may be the cause of the following exception.",
+ self.file.borrow()
+ ))
.into());
}
diff --git a/crates/shirabe/src/command/run_script_command.rs b/crates/shirabe/src/command/run_script_command.rs
index fe020de3..be50c4be 100644
--- a/crates/shirabe/src/command/run_script_command.rs
+++ b/crates/shirabe/src/command/run_script_command.rs
@@ -16,6 +16,7 @@ use shirabe_external_packages::symfony::console::exception::CommandNotFoundExcep
use shirabe_external_packages::symfony::console::exception::namespace_not_found_exception::NamespaceNotFoundException;
use shirabe_external_packages::symfony::console::input::InputInterface;
use shirabe_external_packages::symfony::console::output::OutputInterface;
+use shirabe_php_shim::Catch as _;
use shirabe_php_shim::{InvalidArgumentException, RuntimeException};
use shirabe_php_shim::{PhpMixed, impl_php_class};
@@ -102,8 +103,8 @@ impl RunScriptCommand {
match application.borrow_mut().find(&name) {
Ok(cmd) => description = cmd.borrow().get_description(),
Err(e)
- if e.downcast_ref::<CommandNotFoundException>().is_some()
- || e.downcast_ref::<NamespaceNotFoundException>().is_some() => {}
+ if e.is_instanceof::<CommandNotFoundException>()
+ || e.is_instanceof::<NamespaceNotFoundException>() => {}
Err(e) => return Err(e),
}
}
@@ -255,10 +256,9 @@ impl Command for RunScriptCommand {
let script = match input.borrow().get_argument("script")?.as_string() {
None => {
- return Err(RuntimeException {
- message: "Missing required argument \"script\"".to_string(),
- code: 0,
- }
+ return Err(RuntimeException::new(
+ "Missing required argument \"script\"".to_string(),
+ )
.into());
}
Some(s) => s.to_string(),
@@ -267,10 +267,10 @@ impl Command for RunScriptCommand {
if !self.script_events.contains(&script.as_str()) {
let const_name = script.to_uppercase().replace('-', "_");
if ScriptEvents::is_defined(&const_name) {
- return Err(InvalidArgumentException {
- message: format!("Script \"{}\" cannot be run with this command", script),
- code: 0,
- }
+ return Err(InvalidArgumentException::new(format!(
+ "Script \"{}\" cannot be run with this command",
+ script
+ ))
.into());
}
}
@@ -299,10 +299,10 @@ impl Command for RunScriptCommand {
);
let has_listeners = dispatcher.borrow_mut().has_event_listeners(&event);
if !has_listeners {
- return Err(InvalidArgumentException {
- message: format!("Script \"{}\" is not defined in this package", script),
- code: 0,
- }
+ return Err(InvalidArgumentException::new(format!(
+ "Script \"{}\" is not defined in this package",
+ script
+ ))
.into());
}
@@ -320,12 +320,10 @@ impl Command for RunScriptCommand {
if let Some(timeout_val) = input.borrow().get_option("timeout")?.as_string() {
let timeout_str = timeout_val.to_string();
if !timeout_str.chars().all(|c| c.is_ascii_digit()) {
- return Err(RuntimeException {
- message:
- "Timeout value must be numeric and positive if defined, or 0 for forever"
- .to_string(),
- code: 0,
- }
+ return Err(RuntimeException::new(
+ "Timeout value must be numeric and positive if defined, or 0 for forever"
+ .to_string(),
+ )
.into());
}
let timeout: i64 = timeout_str.parse().unwrap_or(0);
diff --git a/crates/shirabe/src/command/script_alias_command.rs b/crates/shirabe/src/command/script_alias_command.rs
index e6a13545..e3faf3a6 100644
--- a/crates/shirabe/src/command/script_alias_command.rs
+++ b/crates/shirabe/src/command/script_alias_command.rs
@@ -36,12 +36,10 @@ impl ScriptAliasCommand {
for alias in &aliases {
if !is_string(&PhpMixed::String(alias.clone())) {
- return Err(InvalidArgumentException {
- message:
- r#""scripts-aliases" element array values should contain only strings"#
- .to_string(),
- code: 0,
- }
+ return Err(InvalidArgumentException::new(
+ r#""scripts-aliases" element array values should contain only strings"#
+ .to_string(),
+ )
.into());
}
}
@@ -123,10 +121,9 @@ impl Command for ScriptAliasCommand {
// TODO(phase-c): InputInterface has_to_string/get_class_name not modeled in Rust
// TODO remove for Symfony 6+ as it is then in the interface
if false {
- return Err(LogicException {
- message: "Expected an Input instance that is stringable".to_string(),
- code: 0,
- }
+ return Err(LogicException::new(
+ "Expected an Input instance that is stringable".to_string(),
+ )
.into());
}
diff --git a/crates/shirabe/src/command/search_command.rs b/crates/shirabe/src/command/search_command.rs
index 4bf75c8b..51432ed9 100644
--- a/crates/shirabe/src/command/search_command.rs
+++ b/crates/shirabe/src/command/search_command.rs
@@ -181,10 +181,9 @@ impl Command for SearchCommand {
.as_bool()
.unwrap_or(false)
{
- return Err(InvalidArgumentException {
- message: "--only-name and --only-vendor cannot be used together".to_string(),
- code: 0,
- }
+ return Err(InvalidArgumentException::new(
+ "--only-name and --only-vendor cannot be used together".to_string(),
+ )
.into());
}
mode = repository_interface::SEARCH_NAME;
diff --git a/crates/shirabe/src/command/show_command.rs b/crates/shirabe/src/command/show_command.rs
index aa63d8e7..6c693e62 100644
--- a/crates/shirabe/src/command/show_command.rs
+++ b/crates/shirabe/src/command/show_command.rs
@@ -359,14 +359,11 @@ impl ShowCommand {
if let Some(ref mp) = matched_package
&& mp.as_complete().is_none()
{
- return Err(LogicException {
- message: format!(
- "ShowCommand::getPackage can only work with CompletePackageInterface, but got {}",
- shirabe_php_shim::get_class(&PhpMixed::Null)
- ),
- code: 0,
- }
- .into());
+ return Err(LogicException::new(format!(
+ "ShowCommand::getPackage can only work with CompletePackageInterface, but got {}",
+ shirabe_php_shim::get_class(&PhpMixed::Null)
+ ))
+ .into());
}
let matched_package = matched_package.and_then(|mp| mp.as_complete());
@@ -1817,10 +1814,9 @@ impl Command for ShowCommand {
.as_string()
.is_some()
{
- return Err(InvalidArgumentException {
- message: "You cannot use --self together with a package name".to_string(),
- code: 0,
- }
+ return Err(InvalidArgumentException::new(
+ "You cannot use --self together with a package name".to_string(),
+ )
.into());
}
installed_repo = RepositoryInterfaceHandle::new(InstalledRepository::new(vec![
@@ -1931,10 +1927,7 @@ impl Command for ShowCommand {
.borrow_mut()
.is_locked()
{
- return Err(UnexpectedValueException {
- message: "A valid composer.json and composer.lock files is required to run this command with --locked".to_string(),
- code: 0,
- }
+ return Err(UnexpectedValueException::new("A valid composer.json and composer.lock files is required to run this command with --locked".to_string())
.into());
}
let composer_ref = crate::composer::composer_full(composer.as_ref().unwrap());
@@ -2090,14 +2083,11 @@ impl Command for ShowCommand {
.collect::<Vec<_>>(),
)
{
- return Err(InvalidArgumentException {
- message: format!(
- "Package \"{}\" is installed but not a direct dependent of the root package.",
- pkg.get_name()
- ),
- code: 0,
- }
- .into());
+ return Err(InvalidArgumentException::new(format!(
+ "Package \"{}\" is installed but not a direct dependent of the root package.",
+ pkg.get_name()
+ ))
+ .into());
}
if matched_package.is_none() {
@@ -2123,10 +2113,10 @@ impl Command for ShowCommand {
hint.push_str(", try using --available (-a) to show all available packages");
}
- return Err(InvalidArgumentException {
- message: format!("Package \"{}\" not found{}.", pf, hint),
- code: 0,
- }
+ return Err(InvalidArgumentException::new(format!(
+ "Package \"{}\" not found{}.",
+ pf, hint
+ ))
.into());
}
single_package = matched_package;
diff --git a/crates/shirabe/src/command/update_command.rs b/crates/shirabe/src/command/update_command.rs
index c928552a..02f32526 100644
--- a/crates/shirabe/src/command/update_command.rs
+++ b/crates/shirabe/src/command/update_command.rs
@@ -72,10 +72,9 @@ impl UpdateCommand {
packages: Vec<String>,
) -> anyhow::Result<Vec<String>> {
if !input.borrow().is_interactive() {
- return Err(InvalidArgumentException {
- message: "--interactive cannot be used in non-interactive terminals.".to_string(),
- code: 0,
- }
+ return Err(InvalidArgumentException::new(
+ "--interactive cannot be used in non-interactive terminals.".to_string(),
+ )
.into());
}
@@ -165,10 +164,9 @@ impl UpdateCommand {
}
if autocompleter_values.is_empty() {
- return Err(RuntimeException {
- message: "Could not find any package with new versions available".to_string(),
- code: 0,
- }
+ return Err(RuntimeException::new(
+ "Could not find any package with new versions available".to_string(),
+ )
.into());
}
@@ -210,11 +208,7 @@ impl UpdateCommand {
return Ok(packages);
}
- Err(RuntimeException {
- message: "Installation aborted.".to_string(),
- code: 0,
- }
- .into())
+ Err(RuntimeException::new("Installation aborted.".to_string()).into())
}
fn create_version_selector(
@@ -450,10 +444,9 @@ impl Command for UpdateCommand {
.unwrap_or(false)
{
if !composer.get_locker().borrow_mut().is_locked() {
- return Err(InvalidArgumentException {
- message: "patch-only can only be used with a lock file present".to_string(),
- code: 0,
- }
+ return Err(InvalidArgumentException::new(
+ "patch-only can only be used with a lock file present".to_string(),
+ )
.into());
}
for package in composer
diff --git a/crates/shirabe/src/config.rs b/crates/shirabe/src/config.rs
index 154fbd05..300b9bfa 100644
--- a/crates/shirabe/src/config.rs
+++ b/crates/shirabe/src/config.rs
@@ -658,10 +658,10 @@ impl Config {
&raw,
Some(&mut matches),
) {
- return Err(RuntimeException {
- message: format!("Could not parse the value of '{}': {}", key, raw),
- code: 0,
- }
+ return Err(RuntimeException::new(format!(
+ "Could not parse the value of '{}': {}",
+ key, raw
+ ))
.into());
}
let mut size = matches
@@ -735,13 +735,10 @@ impl Config {
PhpMixed::String("symlink".to_string()),
],
) {
- return Err(RuntimeException {
- message: format!(
- "Invalid value for 'bin-compat': {}. Expected auto, full or proxy",
- value
- ),
- code: 0,
- }
+ return Err(RuntimeException::new(format!(
+ "Invalid value for 'bin-compat': {}. Expected auto, full or proxy",
+ value
+ ))
.into());
}
@@ -760,13 +757,10 @@ impl Config {
if !matches!(env, PhpMixed::Bool(false)) {
let env_str = env.as_string().unwrap_or("").to_string();
if !matches!(env_str.as_str(), "stash" | "true" | "false" | "1" | "0") {
- return Err(RuntimeException {
- message: format!(
- "Invalid value for COMPOSER_DISCARD_CHANGES: {}. Expected 1, 0, true, false or stash",
- env_str
- ),
- code: 0,
- }
+ return Err(RuntimeException::new(format!(
+ "Invalid value for COMPOSER_DISCARD_CHANGES: {}. Expected 1, 0, true, false or stash",
+ env_str
+ ))
.into());
}
if env_str == "stash" {
@@ -782,13 +776,10 @@ impl Config {
let val = self.config.get(key).cloned().unwrap_or(PhpMixed::Null);
let allowed = matches!(&val, PhpMixed::Bool(_)) || val.as_string() == Some("stash");
if !allowed {
- return Err(RuntimeException {
- message: format!(
- "Invalid value for 'discard-changes': {:?}. Expected true, false or stash",
- val
- ),
- code: 0,
- }
+ return Err(RuntimeException::new(format!(
+ "Invalid value for 'discard-changes': {:?}. Expected true, false or stash",
+ val
+ ))
.into());
}
@@ -824,10 +815,7 @@ impl Config {
}
let first = protos.first().cloned();
if first.as_deref() == Some("http") {
- return Err(RuntimeException {
- message: "The http protocol for github is not available anymore, update your config's github-protocols to use \"https\", \"git\" or \"ssh\"".to_string(),
- code: 0,
- }
+ return Err(RuntimeException::new("The http protocol for github is not available anymore, update your config's github-protocols to use \"https\", \"git\" or \"ssh\"".to_string())
.into());
}
@@ -860,14 +848,11 @@ impl Config {
.map(|s| PhpMixed::String(s.clone()))
.collect::<Vec<_>>(),
) {
- return Err(RuntimeException {
- message: format!(
- "Invalid value for COMPOSER_AUDIT_ABANDONED: {}. Expected one of {}.",
- abandoned_env_str,
- implode(", ", &valid_choices),
- ),
- code: 0,
- }
+ return Err(RuntimeException::new(format!(
+ "Invalid value for COMPOSER_AUDIT_ABANDONED: {}. Expected one of {}.",
+ abandoned_env_str,
+ implode(", ", &valid_choices),
+ ))
.into());
}
if let PhpMixed::Array(ref mut m) = result {
@@ -880,13 +865,10 @@ impl Config {
if !matches!(block_abandoned_env, PhpMixed::Bool(false)) {
let env_str = block_abandoned_env.as_string().unwrap_or("").to_string();
if !matches!(env_str.as_str(), "0" | "1") {
- return Err(RuntimeException {
- message: format!(
- "Invalid value for COMPOSER_SECURITY_BLOCKING_ABANDONED: {}. Expected 0 or 1.",
- env_str
- ),
- code: 0,
- }
+ return Err(RuntimeException::new(format!(
+ "Invalid value for COMPOSER_SECURITY_BLOCKING_ABANDONED: {}. Expected 0 or 1.",
+ env_str
+ ))
.into());
}
if let PhpMixed::Array(ref mut m) = result {
diff --git a/crates/shirabe/src/config/json_config_source.rs b/crates/shirabe/src/config/json_config_source.rs
index 53e3722b..0257ee31 100644
--- a/crates/shirabe/src/config/json_config_source.rs
+++ b/crates/shirabe/src/config/json_config_source.rs
@@ -7,6 +7,7 @@ use crate::json::JsonValidationException;
use crate::util::Filesystem;
use crate::util::Silencer;
use indexmap::IndexMap;
+use shirabe_php_shim::Catch as _;
use shirabe_php_shim::{
PHP_EOL, PhpMixed, RuntimeException, chmod, explode, file_get_contents, file_put_contents,
implode, is_writable,
@@ -32,24 +33,18 @@ impl JsonConfigSource {
let contents;
if self.file.borrow().exists() {
if !is_writable(self.file.borrow().get_path()) {
- return Err(RuntimeException {
- message: format!(
- "The file \"{}\" is not writable.",
- self.file.borrow().get_path(),
- ),
- code: 0,
- }
+ return Err(RuntimeException::new(format!(
+ "The file \"{}\" is not writable.",
+ self.file.borrow().get_path(),
+ ))
.into());
}
if !Filesystem::is_readable(self.file.borrow().get_path()) {
- return Err(RuntimeException {
- message: format!(
- "The file \"{}\" is not readable.",
- self.file.borrow().get_path(),
- ),
- code: 0,
- }
+ return Err(RuntimeException::new(format!(
+ "The file \"{}\" is not readable.",
+ self.file.borrow().get_path(),
+ ))
.into());
}
@@ -148,19 +143,16 @@ impl JsonConfigSource {
{
Ok(_) => {}
Err(e) => {
- let Some(jve) = e.downcast_ref::<JsonValidationException>() else {
+ let Some(jve) = e.catch::<JsonValidationException>() else {
return Err(e);
};
// restore contents to the original state
file_put_contents(self.file.borrow().get_path(), contents.as_bytes());
- return Err(RuntimeException {
- message: format!(
- "Failed to update composer.json with a valid format, reverting to the original content. Please report an issue to us with details (command you run and a copy of your composer.json). {}{}",
- PHP_EOL,
- implode(PHP_EOL, jve.get_errors()),
- ),
- code: 0,
- }
+ return Err(RuntimeException::new(format!(
+ "Failed to update composer.json with a valid format, reverting to the original content. Please report an issue to us with details (command you run and a copy of your composer.json). {}{}",
+ PHP_EOL,
+ implode(PHP_EOL, jve.get_errors()),
+ ))
.into());
}
}
@@ -397,13 +389,10 @@ impl ConfigSourceInterface for JsonConfigSource {
}
}
let Some(index_to_insert) = index_to_insert else {
- return Err(RuntimeException {
- message: format!(
- "The referenced repository \"{}\" does not exist.",
- reference_name,
- ),
- code: 0,
- }
+ return Err(RuntimeException::new(format!(
+ "The referenced repository \"{}\" does not exist.",
+ reference_name,
+ ))
.into());
};
diff --git a/crates/shirabe/src/console/application.rs b/crates/shirabe/src/console/application.rs
index 96f80d9b..16a67b72 100644
--- a/crates/shirabe/src/console/application.rs
+++ b/crates/shirabe/src/console/application.rs
@@ -93,6 +93,7 @@ use shirabe_external_packages::symfony::console::style::style_interface::StyleIn
use shirabe_external_packages::symfony::console::style::symfony_style::SymfonyStyle;
use shirabe_external_packages::symfony::console::terminal::Terminal;
use shirabe_external_packages::symfony::process::exception::ProcessTimedOutException;
+use shirabe_php_shim::Catch as _;
use shirabe_php_shim::{
LogicException as ShimLogicException, PHP_VERSION, PHP_VERSION_ID, PhpMixed, RuntimeException,
bin2hex, chdir, date_default_timezone_get, date_default_timezone_set, defined, dirname,
@@ -232,13 +233,10 @@ impl Application {
if let Some(ref wd) = working_dir
&& !is_dir(wd)
{
- return Err(RuntimeException {
- message: format!(
- "Invalid working directory specified, {} does not exist.",
- wd
- ),
- code: 0,
- }
+ return Err(RuntimeException::new(format!(
+ "Invalid working directory specified, {} does not exist.",
+ wd
+ ))
.into());
}
@@ -250,8 +248,8 @@ impl Application {
exception: &anyhow::Error,
output: std::rc::Rc<std::cell::RefCell<dyn OutputInterface>>,
) {
- let is_logic_or_error = exception.downcast_ref::<ShimLogicException>().is_some();
- if is_logic_or_error
+ if (exception.is_class::<ShimLogicException>()
+ || exception.is_instanceof::<shirabe_php_shim::Error>())
&& output.borrow().get_verbosity() < output_interface::VERBOSITY_VERBOSE
{
output
@@ -308,7 +306,7 @@ impl Application {
}
let message = exception.to_string();
- if exception.downcast_ref::<TransportException>().is_some()
+ if exception.is_instanceof::<TransportException>()
&& str_contains(&message, "Unable to use a proxy")
{
io.write_error3(
@@ -320,7 +318,7 @@ impl Application {
}
if Platform::is_windows()
- && exception.downcast_ref::<TransportException>().is_some()
+ && exception.is_instanceof::<TransportException>()
&& str_contains(&message, "unable to get local issuer certificate")
{
let avast_detect = glob("C:\\Program Files\\Avast*");
@@ -359,10 +357,7 @@ impl Application {
io.write_error3("<error>Check https://getcomposer.org/doc/articles/troubleshooting.md#proc-open-fork-failed-errors for details</error>", true, io_interface::QUIET);
}
- if exception
- .downcast_ref::<ProcessTimedOutException>()
- .is_some()
- {
+ if exception.is_instanceof::<ProcessTimedOutException>() {
io.write_error3(
"<error>The following exception is caused by a process timeout</error>",
true,
@@ -376,9 +371,7 @@ impl Application {
&& !self.io.is_interactive()
{
io.write_error3("<error>Plugins have been disabled automatically as you are running as root, this may be the cause of the following exception. See also https://getcomposer.org/root</error>", true, io_interface::QUIET);
- } else if exception
- .downcast_ref::<CommandNotFoundException>()
- .is_some()
+ } else if exception.is_instanceof::<CommandNotFoundException>()
&& self.get_disable_plugins_by_default()
{
io.write_error3("<error>Plugins have been disabled, which may be why some commands are missing, unless you made a typo</error>", true, io_interface::QUIET);
@@ -416,9 +409,7 @@ impl Application {
match Factory::create(io_for_factory, None, disable_plugins_enum, disable_scripts) {
Ok(c) => self.composer = Some(c.upcast()),
Err(e) => {
- if e.downcast_ref::<shirabe_php_shim::InvalidArgumentException>()
- .is_some()
- {
+ if e.is_instanceof::<shirabe_php_shim::InvalidArgumentException>() {
if required {
self.io.write_error(&e.to_string());
if self.are_exceptions_caught() {
@@ -429,11 +420,11 @@ impl Application {
}
return Err(e);
}
- } else if e.downcast_ref::<JsonValidationException>().is_some()
- || e.downcast_ref::<RuntimeException>().is_some()
+ } else if e.is_instanceof::<JsonValidationException>()
+ || e.is_instanceof::<RuntimeException>()
// PHP's `catch (RuntimeException)` also catches subclasses;
// NoSslException is the one Factory::create raises.
- || e.downcast_ref::<NoSslException>().is_some()
+ || e.is_instanceof::<NoSslException>()
{
if required {
return Err(e);
@@ -523,7 +514,7 @@ impl Application {
Ok(()) => {}
Err(e) => {
// Errors must be ignored, full binding/validation happens later when the command is known.
- if !is_exception_interface(&e) {
+ if !throwable_is_exception_interface(e.as_ref()) {
return Err(e);
}
}
@@ -712,10 +703,7 @@ impl Application {
pub fn get_signal_registry(&self) -> anyhow::Result<&SignalRegistry> {
match &self.signal_registry {
- None => Err(ConsoleRuntimeException(shirabe_php_shim::RuntimeException {
- message: "Signals are not supported. Make sure that the `pcntl` extension is installed and that \"pcntl_*\" functions are not disabled by your php.ini's \"disable_functions\" directive.".to_string(),
- code: 0,
- })
+ None => Err(ConsoleRuntimeException::new("Signals are not supported. Make sure that the `pcntl` extension is installed and that \"pcntl_*\" functions are not disabled by your php.ini's \"disable_functions\" directive.".to_string())
.into()),
Some(signal_registry) => Ok(signal_registry),
}
@@ -988,17 +976,12 @@ impl Application {
message.push_str(&shirabe_php_shim::implode("\n ", &alternatives));
}
- return Err(NamespaceNotFoundException(CommandNotFoundException::new(
- message,
- alternatives,
- 0,
- ))
- .into());
+ return Err(NamespaceNotFoundException::new(message, alternatives, 0).into());
}
let exact = namespaces.iter().any(|n| n == namespace);
if namespaces.len() > 1 && !exact {
- return Err(NamespaceNotFoundException(CommandNotFoundException::new(
+ return Err(NamespaceNotFoundException::new(
format!(
"The namespace \"{}\" is ambiguous.\nDid you mean one of these?\n{}.",
namespace,
@@ -1006,7 +989,7 @@ impl Application {
),
namespaces,
0,
- ))
+ )
.into());
}
@@ -1936,13 +1919,10 @@ impl ApplicationHandle {
command.borrow().get_definition();
if command.borrow().get_name().is_none() {
- return Err(ConsoleLogicException(shirabe_php_shim::LogicException {
- message: format!(
- "The command defined in \"{}\" cannot have an empty name.",
- shirabe_php_shim::get_debug_type_obj(&command),
- ),
- code: 0,
- })
+ return Err(ConsoleLogicException::new(format!(
+ "The command defined in \"{}\" cannot have an empty name.",
+ shirabe_php_shim::get_debug_type_obj(&command),
+ ))
.into());
}
@@ -2057,7 +2037,7 @@ impl ApplicationHandle {
command_name = cmd.borrow().get_name();
}
Err(e) => {
- if e.downcast_ref::<CommandNotFoundException>().is_some() {
+ if e.is_instanceof::<CommandNotFoundException>() {
// we'll check command validity again later after plugins are loaded
command_name = None;
}
@@ -2223,9 +2203,9 @@ impl ApplicationHandle {
})() {
Ok(_) => {}
Err(e) => {
- if e.downcast_ref::<NoSslException>().is_some() {
+ if e.is_instanceof::<NoSslException>() {
// suppress these as they are not relevant at this point
- } else if let Some(pe) = e.downcast_ref::<ParsingException>() {
+ } else if let Some(pe) = e.catch::<ParsingException>() {
let details = pe.get_details();
let file = realpath(Factory::get_composer_file().unwrap_or_default());
@@ -2233,7 +2213,7 @@ impl ApplicationHandle {
let line = details.line;
let mut ghe = GithubActionError::new(io.clone());
- ghe.emit(&pe.message, file.as_deref(), line);
+ ghe.emit(pe.get_message(), file.as_deref(), line);
return Err(e);
} else {
@@ -2542,7 +2522,7 @@ impl ApplicationHandle {
let outcome = match result_outcome {
Ok(r) => Ok(r),
- Err(e) => {
+ Err(mut e) => {
// PHP's `exit` bypasses parent::doRun()'s catch entirely; re-raise it untouched so
// the GitHub Actions annotation and error hints below are skipped.
if e.downcast_ref::<shirabe_php_shim::ExitException>()
@@ -2550,7 +2530,7 @@ impl ApplicationHandle {
{
return Err(e);
}
- if let Some(see) = e.downcast_ref::<ScriptExecutionException>() {
+ if let Some(see) = e.catch::<ScriptExecutionException>() {
if application.borrow().get_disable_plugins_by_default()
&& application.borrow().is_running_as_root()
&& !io.is_interactive()
@@ -2572,15 +2552,9 @@ impl ApplicationHandle {
// override TransportException's code for the purpose of parent::run() using it as process exit code
// as http error codes are all beyond the 255 range of permitted exit codes
- // TODO(phase-c): PHP's `instanceof TransportException` also matches the subclass
- // MaxFileSizeExceededException, which is a newtype here and is not matched by this downcast.
- let e = match e.downcast::<TransportException>() {
- Ok(mut e) => {
- e.code = Installer::ERROR_TRANSPORT_EXCEPTION;
- anyhow::Error::new(e)
- }
- Err(e) => e,
- };
+ if let Some(te) = e.catch_mut::<TransportException>() {
+ te.set_code(Installer::ERROR_TRANSPORT_EXCEPTION);
+ }
Err(e)
}
@@ -2691,9 +2665,7 @@ impl ApplicationHandle {
// $exitCode = $e->getCode();
// is_numeric($exitCode) ? max(1, (int) $exitCode) : 1
- // TODO(phase-c): anyhow::Error has no PHP-style getCode(); the exit code derived
- // from the exception's `code` field needs the downcast strategy decided.
- let exit_code = shirabe_php_shim::php_exception_get_code(&e);
+ let exit_code = throwable_get_code(e.as_ref()) as i32;
if shirabe_php_shim::is_numeric_string(&exit_code.to_string()) {
if exit_code <= 0 { 1 } else { exit_code }
} else {
@@ -2735,7 +2707,7 @@ impl ApplicationHandle {
Ok(()) => {}
Err(e) => {
// Errors must be ignored, full binding/validation happens later when the command is known.
- if !is_exception_interface(&e) {
+ if !throwable_is_exception_interface(e.as_ref()) {
return Err(e);
}
}
@@ -2814,8 +2786,9 @@ impl ApplicationHandle {
Err(e) => {
// if (!($e instanceof CommandNotFoundException && !$e instanceof NamespaceNotFoundException)
// || 1 !== count($alternatives = $e->getAlternatives()) || !$input->isInteractive())
- let alternatives: Option<Vec<String>> = downcast_command_not_found(&e)
- .filter(|_| !is_namespace_not_found(&e))
+ let alternatives: Option<Vec<String>> = e
+ .catch::<CommandNotFoundException>()
+ .filter(|_| !e.is_instanceof::<NamespaceNotFoundException>())
.map(|cnf| cnf.get_alternatives().clone());
let single_alternative = match &alternatives {
@@ -2907,10 +2880,7 @@ impl ApplicationHandle {
if !command_signals.is_empty() {
if application.borrow().signal_registry.is_none() {
- return Err(ConsoleRuntimeException(shirabe_php_shim::RuntimeException {
- message: "Unable to subscribe to signal events. Make sure that the `pcntl` extension is installed and that \"pcntl_*\" functions are not disabled by your php.ini's \"disable_functions\" directive.".to_string(),
- code: 0,
- })
+ return Err(ConsoleRuntimeException::new("Unable to subscribe to signal events. Make sure that the `pcntl` extension is installed and that \"pcntl_*\" functions are not disabled by your php.ini's \"disable_functions\" directive.".to_string())
.into());
}
@@ -2994,133 +2964,35 @@ impl BaseApplication for Application {
}
}
-/// Helper mirroring PHP's `$e instanceof ExceptionInterface`.
-fn is_exception_interface(e: &anyhow::Error) -> bool {
- // anyhow::Error stores concrete error types; enumerate the console exceptions
- // that implement ExceptionInterface (PHP's `$e instanceof ExceptionInterface`).
- e.downcast_ref::<CommandNotFoundException>().is_some()
- || e.downcast_ref::<NamespaceNotFoundException>().is_some()
- || e.downcast_ref::<ConsoleLogicException>().is_some()
- || e.downcast_ref::<ConsoleRuntimeException>().is_some()
- || e.downcast_ref::<ConsoleInvalidArgumentException>()
- .is_some()
- || e.downcast_ref::<InvalidOptionException>().is_some()
- || e.downcast_ref::<MissingInputException>().is_some()
-}
-
-/// `is_exception_interface` for a node of the `anyhow::Error` source chain (`&dyn Error`), used
-/// while walking the getPrevious() chain in `do_render_throwable`.
+/// PHP's `$e instanceof ExceptionInterface`, enumerating the console exceptions that implement it.
+// TODO(plugin): a plugin can throw an exception class of its own that implements
+// ExceptionInterface, and no enumeration on this side can name it. Answering that needs the
+// interfaces a thrown exception implements, not just its superclasses.
fn throwable_is_exception_interface(e: &(dyn std::error::Error + 'static)) -> bool {
- e.downcast_ref::<CommandNotFoundException>().is_some()
- || e.downcast_ref::<NamespaceNotFoundException>().is_some()
- || e.downcast_ref::<ConsoleLogicException>().is_some()
- || e.downcast_ref::<ConsoleRuntimeException>().is_some()
- || e.downcast_ref::<ConsoleInvalidArgumentException>()
- .is_some()
- || e.downcast_ref::<InvalidOptionException>().is_some()
- || e.downcast_ref::<MissingInputException>().is_some()
+ shirabe_php_shim::AnyThrowable::of(e).is_some_and(|e| {
+ e.is_instanceof::<CommandNotFoundException>()
+ || e.is_instanceof::<NamespaceNotFoundException>()
+ || e.is_instanceof::<ConsoleLogicException>()
+ || e.is_instanceof::<ConsoleRuntimeException>()
+ || e.is_instanceof::<ConsoleInvalidArgumentException>()
+ || e.is_instanceof::<InvalidOptionException>()
+ || e.is_instanceof::<MissingInputException>()
+ })
}
-/// PHP's `$e->getCode()` for a node of the source chain. Enumerates the flat standard exception
-/// structs that carry a `code`; everything else defaults to PHP's 0.
+/// PHP's `$e->getCode()` for a node of the source chain; everything the port does not recognize as
+/// an exception defaults to PHP's 0.
fn throwable_get_code(e: &(dyn std::error::Error + 'static)) -> i64 {
- if let Some(e) = e.downcast_ref::<shirabe_php_shim::Exception>() {
- return e.code;
- }
- if let Some(e) = e.downcast_ref::<shirabe_php_shim::RuntimeException>() {
- return e.code;
- }
- if let Some(e) = e.downcast_ref::<shirabe_php_shim::UnexpectedValueException>() {
- return e.code;
- }
- if let Some(e) = e.downcast_ref::<shirabe_php_shim::InvalidArgumentException>() {
- return e.code;
- }
- if let Some(e) = e.downcast_ref::<shirabe_php_shim::TypeError>() {
- return e.code;
- }
- if let Some(e) = e.downcast_ref::<shirabe_php_shim::LogicException>() {
- return e.code;
- }
- if let Some(e) = e.downcast_ref::<shirabe_php_shim::BadMethodCallException>() {
- return e.code;
- }
- if let Some(e) = e.downcast_ref::<shirabe_php_shim::OutOfBoundsException>() {
- return e.code;
- }
- if let Some(e) = e.downcast_ref::<shirabe_php_shim::ErrorException>() {
- return e.code;
- }
- if let Some(e) = e.downcast_ref::<shirabe_php_shim::PharException>() {
- return e.code;
- }
- 0
+ shirabe_php_shim::AnyThrowable::of(e).map_or(0, shirabe_php_shim::AnyThrowable::get_code)
}
/// PHP's `get_debug_type($e)` for the title line, reached only when the message is empty or output
-/// is verbose. PHP returns the exception's fully-qualified class name; Rust has no runtime FQCN, so
-/// this maps the enumerable exception types to their PHP class names and falls back to `Exception`.
-/// TODO(phase-c): the fully-qualified name (e.g. `Composer\...`) cannot be reproduced faithfully.
+/// is verbose.
fn throwable_debug_type(e: &(dyn std::error::Error + 'static)) -> String {
- let name = if e
- .downcast_ref::<shirabe_php_shim::RuntimeException>()
- .is_some()
- {
- "RuntimeException"
- } else if e
- .downcast_ref::<shirabe_php_shim::UnexpectedValueException>()
- .is_some()
- {
- "UnexpectedValueException"
- } else if e
- .downcast_ref::<shirabe_php_shim::InvalidArgumentException>()
- .is_some()
- {
- "InvalidArgumentException"
- } else if e.downcast_ref::<shirabe_php_shim::TypeError>().is_some() {
- "TypeError"
- } else if e
- .downcast_ref::<shirabe_php_shim::LogicException>()
- .is_some()
- {
- "LogicException"
- } else if e
- .downcast_ref::<shirabe_php_shim::BadMethodCallException>()
- .is_some()
- {
- "BadMethodCallException"
- } else if e
- .downcast_ref::<shirabe_php_shim::OutOfBoundsException>()
- .is_some()
- {
- "OutOfBoundsException"
- } else if e
- .downcast_ref::<shirabe_php_shim::ErrorException>()
- .is_some()
- {
- "ErrorException"
- } else if e
- .downcast_ref::<shirabe_php_shim::PharException>()
- .is_some()
- {
- "PharException"
- } else {
- "Exception"
- };
- name.to_string()
-}
-
-/// Helper mirroring PHP's `$e instanceof CommandNotFoundException`.
-fn downcast_command_not_found(e: &anyhow::Error) -> Option<&CommandNotFoundException> {
- if let Some(cnf) = e.downcast_ref::<CommandNotFoundException>() {
- return Some(cnf);
- }
- e.downcast_ref::<NamespaceNotFoundException>().map(|n| &n.0)
-}
-
-/// Helper mirroring PHP's `$e instanceof NamespaceNotFoundException`.
-fn is_namespace_not_found(e: &anyhow::Error) -> bool {
- e.downcast_ref::<NamespaceNotFoundException>().is_some()
+ shirabe_php_shim::AnyThrowable::of(e).map_or_else(
+ || "Exception".to_string(),
+ shirabe_php_shim::PhpClass::php_class_name,
+ )
}
/// Borrows the shared input as a mutable `dyn InputInterface` for passing to
@@ -3161,13 +3033,11 @@ pub(crate) fn register_worker_reverse_application(
pub(crate) fn run_worker_reverse_command(name: &str, input_line: &str) -> anyhow::Result<i64> {
let application = WORKER_REVERSE_APPLICATION
.with(|slot| slot.borrow().as_ref().and_then(std::rc::Weak::upgrade))
- .ok_or_else(|| {
- anyhow::anyhow!(shirabe_php_shim::RuntimeException {
- message: format!(
- "cannot run command {name}: no application is registered for worker callbacks"
- ),
- code: 0,
- })
+ .ok_or_else(|| -> anyhow::Error {
+ shirabe_php_shim::RuntimeException::new(format!(
+ "cannot run command {name}: no application is registered for worker callbacks"
+ ))
+ .into()
})?;
let command = application.borrow_mut().find(name)?;
// PHP's `(string) $input` omits the command name when the input was built without an
diff --git a/crates/shirabe/src/dependency_resolver/decisions.rs b/crates/shirabe/src/dependency_resolver/decisions.rs
index 81f00884..ac596054 100644
--- a/crates/shirabe/src/dependency_resolver/decisions.rs
+++ b/crates/shirabe/src/dependency_resolver/decisions.rs
@@ -102,14 +102,11 @@ impl Decisions {
panic!(
"{}",
- LogicException {
- message: format!(
- "Did not find a decision rule using {}",
- literal_or_package_id
- ),
- code: 0,
- }
- .message
+ LogicException::new(format!(
+ "Did not find a decision rule using {}",
+ literal_or_package_id
+ ))
+ .get_message()
);
}
@@ -171,7 +168,7 @@ impl Decisions {
literal_string, level, package, previous_decision
))
.0
- .message
+ .get_message()
);
}
diff --git a/crates/shirabe/src/dependency_resolver/generic_rule.rs b/crates/shirabe/src/dependency_resolver/generic_rule.rs
index 8b64dc46..3f098f01 100644
--- a/crates/shirabe/src/dependency_resolver/generic_rule.rs
+++ b/crates/shirabe/src/dependency_resolver/generic_rule.rs
@@ -44,11 +44,7 @@ impl GenericRule {
let binary = hash_raw(algo, &joined);
match binary.get(..4) {
Some(chunk) => Ok(i32::from_ne_bytes(chunk.try_into().unwrap()) as i64),
- None => Err(RuntimeException {
- message: format!("Failed unpacking: {}", joined),
- code: 0,
- }
- .into()),
+ None => Err(RuntimeException::new(format!("Failed unpacking: {}", joined)).into()),
}
}
diff --git a/crates/shirabe/src/dependency_resolver/multi_conflict_rule.rs b/crates/shirabe/src/dependency_resolver/multi_conflict_rule.rs
index 0936dd0c..d43d9a79 100644
--- a/crates/shirabe/src/dependency_resolver/multi_conflict_rule.rs
+++ b/crates/shirabe/src/dependency_resolver/multi_conflict_rule.rs
@@ -16,10 +16,9 @@ impl MultiConflictRule {
reason_data: ReasonData,
) -> anyhow::Result<Self> {
if literals.len() < 3 {
- return Err(RuntimeException {
- message: "multi conflict rule requires at least 3 literals".to_string(),
- code: 0,
- }
+ return Err(RuntimeException::new(
+ "multi conflict rule requires at least 3 literals".to_string(),
+ )
.into());
}
@@ -59,11 +58,7 @@ impl MultiConflictRule {
let binary = hash_raw(algo, &format!("c:{}", joined));
match binary.get(..4) {
Some(chunk) => Ok(i32::from_ne_bytes(chunk.try_into().unwrap()) as i64),
- None => Err(RuntimeException {
- message: format!("Failed unpacking: {}", joined),
- code: 0,
- }
- .into()),
+ None => Err(RuntimeException::new(format!("Failed unpacking: {}", joined)).into()),
}
}
diff --git a/crates/shirabe/src/dependency_resolver/pool_builder.rs b/crates/shirabe/src/dependency_resolver/pool_builder.rs
index 35699a90..f5143897 100644
--- a/crates/shirabe/src/dependency_resolver/pool_builder.rs
+++ b/crates/shirabe/src/dependency_resolver/pool_builder.rs
@@ -147,11 +147,9 @@ impl PoolBuilder {
self.warn_about_non_matching_update_allow_list(request)?;
if request.get_locked_repository().is_none() {
- return Err(LogicException {
- message: "No lock repo present and yet a partial update was requested."
- .to_string(),
- code: 0,
- }
+ return Err(LogicException::new(
+ "No lock repo present and yet a partial update was requested.".to_string(),
+ )
.into());
}
@@ -798,10 +796,9 @@ impl PoolBuilder {
fn warn_about_non_matching_update_allow_list(&self, request: &Request) -> anyhow::Result<()> {
if request.get_locked_repository().is_none() {
- return Err(LogicException {
- message: "No lock repo present and yet a partial update was requested.".to_string(),
- code: 0,
- }
+ return Err(LogicException::new(
+ "No lock repo present and yet a partial update was requested.".to_string(),
+ )
.into());
}
diff --git a/crates/shirabe/src/dependency_resolver/problem.rs b/crates/shirabe/src/dependency_resolver/problem.rs
index 3c69babe..3b9feba5 100644
--- a/crates/shirabe/src/dependency_resolver/problem.rs
+++ b/crates/shirabe/src/dependency_resolver/problem.rs
@@ -82,10 +82,9 @@ impl Problem {
let rule_ref = rule.borrow();
if rule_ref.get_reason() != rule::RULE_ROOT_REQUIRE {
- return Err(LogicException {
- message: "Single reason problems must contain a root require rule.".to_string(),
- code: 0,
- }
+ return Err(LogicException::new(
+ "Single reason problems must contain a root require rule.".to_string(),
+ )
.into());
}
diff --git a/crates/shirabe/src/dependency_resolver/request.rs b/crates/shirabe/src/dependency_resolver/request.rs
index d78900c0..410831dd 100644
--- a/crates/shirabe/src/dependency_resolver/request.rs
+++ b/crates/shirabe/src/dependency_resolver/request.rs
@@ -47,15 +47,12 @@ impl Request {
let package_name = strtolower(package_name);
let constraint = constraint.unwrap_or_else(|| MatchAllConstraint::new(None).into());
if self.requires.contains_key(&package_name) {
- return Err(LogicException {
- message: format!(
- "Overwriting requires seems like a bug ({} {} => {}, check why it is happening, might be a root alias",
- package_name,
- self.requires[&package_name].get_pretty_string(),
- constraint.get_pretty_string()
- ),
- code: 0,
- }
+ return Err(LogicException::new(format!(
+ "Overwriting requires seems like a bug ({} {} => {}, check why it is happening, might be a root alias",
+ package_name,
+ self.requires[&package_name].get_pretty_string(),
+ constraint.get_pretty_string()
+ ))
.into());
}
self.requires.insert(package_name, constraint);
diff --git a/crates/shirabe/src/dependency_resolver/rule.rs b/crates/shirabe/src/dependency_resolver/rule.rs
index 0ed442ce..5e009260 100644
--- a/crates/shirabe/src/dependency_resolver/rule.rs
+++ b/crates/shirabe/src/dependency_resolver/rule.rs
@@ -166,10 +166,7 @@ impl Rule {
pub fn disable(&mut self) -> anyhow::Result<()> {
if let Rule::MultiConflict(_) = self {
- return Err(RuntimeException {
- message: "Disabling multi conflict rules is not possible. Please contact composer at https://github.com/composer/composer to let us debug what lead to this situation.".to_string(),
- code: 0,
- }
+ return Err(RuntimeException::new("Disabling multi conflict rules is not possible. Please contact composer at https://github.com/composer/composer to let us debug what lead to this situation.".to_string())
.into());
}
*self.bitfield_mut() =
@@ -291,11 +288,7 @@ impl Rule {
Ok(source_package)
}
- _ => Err(LogicException {
- message: "Not implemented".to_string(),
- code: 0,
- }
- .into()),
+ _ => Err(LogicException::new("Not implemented".to_string()).into()),
}
}
diff --git a/crates/shirabe/src/dependency_resolver/rule_set.rs b/crates/shirabe/src/dependency_resolver/rule_set.rs
index f7300d93..50f7cb45 100644
--- a/crates/shirabe/src/dependency_resolver/rule_set.rs
+++ b/crates/shirabe/src/dependency_resolver/rule_set.rs
@@ -59,11 +59,7 @@ impl RuleSet {
) -> anyhow::Result<()> {
let types = Self::types();
if !types.contains_key(&r#type) {
- return Err(OutOfBoundsException {
- message: format!("Unknown rule type: {}", r#type),
- code: 0,
- }
- .into());
+ return Err(OutOfBoundsException::new(format!("Unknown rule type: {}", r#type)).into());
}
let hash = rule.borrow().get_hash()?.to_string();
diff --git a/crates/shirabe/src/dependency_resolver/rule_set_generator.rs b/crates/shirabe/src/dependency_resolver/rule_set_generator.rs
index 2f4837d4..6f2213dc 100644
--- a/crates/shirabe/src/dependency_resolver/rule_set_generator.rs
+++ b/crates/shirabe/src/dependency_resolver/rule_set_generator.rs
@@ -309,13 +309,11 @@ impl RuleSetGenerator {
}
// otherwise, looks like a bug
- return Err(anyhow::anyhow!(shirabe_php_shim::LogicException {
- message: format!(
- "Fixed package {} was not added to solver pool.",
- package.get_pretty_string()
- ),
- code: 0,
- }));
+ return Err(shirabe_php_shim::LogicException::new(format!(
+ "Fixed package {} was not added to solver pool.",
+ package.get_pretty_string()
+ ))
+ .into());
}
self.add_rules_for_package(package.clone(), platform_requirement_filter);
diff --git a/crates/shirabe/src/dependency_resolver/solver.rs b/crates/shirabe/src/dependency_resolver/solver.rs
index dd5bd383..a9453a3e 100644
--- a/crates/shirabe/src/dependency_resolver/solver.rs
+++ b/crates/shirabe/src/dependency_resolver/solver.rs
@@ -381,10 +381,11 @@ impl Solver {
let (learn_literal, new_level, new_rule, why) = self.analyze(level, rule)?;
if new_level <= 0 || new_level >= level {
- return Err(anyhow::anyhow!(SolverBugException::new(format!(
+ return Err(SolverBugException::new(format!(
"Trying to revert to invalid level {} from level {}.",
new_level, level
- ))));
+ ))
+ .into());
}
level = new_level;
@@ -505,12 +506,12 @@ impl Solver {
let inner_literal = loop {
if decision_id <= 0 {
- return Err(anyhow::anyhow!(SolverBugException::new(format!(
+ return Err(SolverBugException::new(format!(
"Reached invalid decision id {} while looking through {} for a literal present in the analyzed rule {}.",
decision_id,
rule.borrow(),
analyzed_rule.borrow()
- ))));
+ )).into());
}
decision_id -= 1;
@@ -587,10 +588,11 @@ impl Solver {
let learned_literal = match learned_literal {
Some(l) => l,
None => {
- return Err(anyhow::anyhow!(SolverBugException::new(format!(
+ return Err(SolverBugException::new(format!(
"Did not find a learnable literal in analyzed rule {}.",
analyzed_rule.borrow()
- ))));
+ ))
+ .into());
}
};
diff --git a/crates/shirabe/src/dependency_resolver/solver_bug_exception.rs b/crates/shirabe/src/dependency_resolver/solver_bug_exception.rs
index d509ef6a..9c47d99b 100644
--- a/crates/shirabe/src/dependency_resolver/solver_bug_exception.rs
+++ b/crates/shirabe/src/dependency_resolver/solver_bug_exception.rs
@@ -12,17 +12,12 @@ impl SolverBugException {
Please report the command you ran, the exact error you received, and your composer.json on https://github.com/composer/composer/issues - thank you!\n",
message
);
- SolverBugException(RuntimeException {
- message: full_message,
- code: 0,
- })
+ SolverBugException(RuntimeException::new(full_message))
}
}
-impl std::fmt::Display for SolverBugException {
- fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
- self.0.fmt(f)
- }
-}
-
-impl std::error::Error for SolverBugException {}
+shirabe_php_shim::impl_php_exception!(
+ SolverBugException,
+ 0,
+ r"Composer\DependencyResolver\SolverBugException"
+);
diff --git a/crates/shirabe/src/dependency_resolver/solver_problems_exception.rs b/crates/shirabe/src/dependency_resolver/solver_problems_exception.rs
index 39f2b2c1..4c948608 100644
--- a/crates/shirabe/src/dependency_resolver/solver_problems_exception.rs
+++ b/crates/shirabe/src/dependency_resolver/solver_problems_exception.rs
@@ -18,14 +18,6 @@ pub struct SolverProblemsException {
impl SolverProblemsException {
pub const ERROR_DEPENDENCY_RESOLUTION_FAILED: i64 = 2;
- pub fn get_code(&self) -> i64 {
- self.inner.code
- }
-
- pub fn get_message(&self) -> &str {
- &self.inner.message
- }
-
pub fn new(
problems: Vec<Problem>,
learned_pool: Vec<Vec<std::rc::Rc<std::cell::RefCell<Rule>>>>,
@@ -35,10 +27,7 @@ impl SolverProblemsException {
problems.len()
);
Self {
- inner: RuntimeException {
- message,
- code: Self::ERROR_DEPENDENCY_RESOLUTION_FAILED,
- },
+ inner: RuntimeException::with_code(message, Self::ERROR_DEPENDENCY_RESOLUTION_FAILED),
problems,
learned_pool,
}
@@ -170,10 +159,11 @@ impl SolverProblemsException {
}
}
-impl std::fmt::Display for SolverProblemsException {
- fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
- write!(f, "{}", self.inner.message)
- }
-}
-
-impl std::error::Error for SolverProblemsException {}
+// `learned_pool` holds `Rc<RefCell<Rule>>`, so this exception rides an inner `Result` rather than
+// an `anyhow::Error`.
+shirabe_php_shim::impl_php_exception!(
+ SolverProblemsException,
+ inner,
+ r"Composer\DependencyResolver\SolverProblemsException",
+ !Send
+);
diff --git a/crates/shirabe/src/downloader/archive_downloader.rs b/crates/shirabe/src/downloader/archive_downloader.rs
index 6ddf29b6..d2ee4a75 100644
--- a/crates/shirabe/src/downloader/archive_downloader.rs
+++ b/crates/shirabe/src/downloader/archive_downloader.rs
@@ -9,6 +9,7 @@ use crate::util::Filesystem;
use crate::util::Platform;
use indexmap::IndexMap;
use shirabe_external_packages::symfony::finder::Finder;
+use shirabe_php_shim::Catch as _;
use shirabe_php_shim::{
DIRECTORY_SEPARATOR, PhpMixed, RuntimeException, bin2hex, file_exists, is_dir, random_bytes,
realpath,
@@ -155,7 +156,7 @@ pub trait ArchiveDownloader {
Ok(false) => {}
Err(e) => {
// ignore error, and simply do not renameAsOne
- if e.downcast_ref::<RuntimeException>().is_none() {
+ if !e.is_instanceof::<RuntimeException>() {
return Err(e);
}
}
@@ -273,14 +274,11 @@ fn rename_recursively(
);
if is_dir(&target) {
if !is_dir(file) {
- return Err(RuntimeException {
- message: format!(
- "Installing {} would lead to overwriting the {} directory with a file from the package, invalid operation.",
- package,
- target.display()
- ),
- code: 0,
- }
+ return Err(RuntimeException::new(format!(
+ "Installing {} would lead to overwriting the {} directory with a file from the package, invalid operation.",
+ package,
+ target.display()
+ ))
.into());
}
rename_recursively(filesystem, package.clone(), file, &target)?;
diff --git a/crates/shirabe/src/downloader/download_manager.rs b/crates/shirabe/src/downloader/download_manager.rs
index 423eda28..8c10de5d 100644
--- a/crates/shirabe/src/downloader/download_manager.rs
+++ b/crates/shirabe/src/downloader/download_manager.rs
@@ -9,6 +9,7 @@ use crate::package::PackageInterfaceHandle;
use crate::util::Filesystem;
use indexmap::IndexMap;
use shirabe_external_packages::composer::pcre::Preg;
+use shirabe_php_shim::Catch as _;
use shirabe_php_shim::{
InvalidArgumentException, LogicException, PhpMixed, RuntimeException, array_keys,
array_reverse, array_shift, dirname, implode, in_array_strict, preg_quote, rtrim, str_replace,
@@ -99,14 +100,11 @@ impl DownloadManager {
) -> anyhow::Result<std::rc::Rc<std::cell::RefCell<dyn DownloaderInterface>>> {
let r#type = strtolower(r#type);
if !self.downloaders.contains_key(&r#type) {
- return Err(InvalidArgumentException {
- message: format!(
- "Unknown downloader type: {}. Available types: {}.",
- r#type,
- implode(", ", &array_keys(&self.downloaders)),
- ),
- code: 0,
- }
+ return Err(InvalidArgumentException::new(format!(
+ "Unknown downloader type: {}. Available types: {}.",
+ r#type,
+ implode(", ", &array_keys(&self.downloaders)),
+ ))
.into());
}
@@ -134,28 +132,22 @@ impl DownloadManager {
} else if installation_source.as_deref() == Some("source") {
self.get_downloader(&package.get_source_type().unwrap_or_default())?
} else {
- return Err(InvalidArgumentException {
- message: format!(
- "Package {} does not have an installation source set",
- package,
- ),
- code: 0,
- }
+ return Err(InvalidArgumentException::new(format!(
+ "Package {} does not have an installation source set",
+ package,
+ ))
.into());
};
let downloader_installation_source = downloader.borrow().get_installation_source();
if installation_source.as_deref() != Some(&downloader_installation_source) {
- return Err(LogicException {
- message: format!(
- "Downloader \"{}\" is a {} type downloader and can not be used to download {} for package {}",
- downloader.borrow().php_class_name(),
- downloader_installation_source,
- installation_source.unwrap_or_default(),
- package,
- ),
- code: 0,
- }
+ return Err(LogicException::new(format!(
+ "Downloader \"{}\" is a {} type downloader and can not be used to download {} for package {}",
+ downloader.borrow().php_class_name(),
+ downloader_installation_source,
+ installation_source.unwrap_or_default(),
+ package,
+ ))
.into());
}
@@ -227,19 +219,18 @@ impl DownloadManager {
{
Ok(r) => r,
Err(e) => {
- let is_runtime = e.downcast_ref::<RuntimeException>().is_some();
- let is_irrecoverable =
- e.downcast_ref::<IrrecoverableDownloadException>().is_some();
- if is_runtime && !is_irrecoverable {
+ if e.is_instanceof::<RuntimeException>()
+ && !e.is_instanceof::<IrrecoverableDownloadException>()
+ {
if sources.is_empty() {
return Err(e);
}
let message = e
- .downcast_ref::<RuntimeException>()
+ .catch::<RuntimeException>()
.unwrap()
- .message
- .clone();
+ .get_message()
+ .to_string();
self.io.write_error3(
&format!(
" <warning>Failed to download {} from {}: {}</warning>",
@@ -352,17 +343,17 @@ impl DownloadManager {
Ok(p) => return Ok(p),
Err(e) => {
// PHP catches only \RuntimeException; other exceptions propagate uncaught.
- if e.downcast_ref::<RuntimeException>().is_none() {
+ if !e.is_instanceof::<RuntimeException>() {
return Err(e);
}
if !self.io.is_interactive() {
return Err(e);
}
let message = e
- .downcast_ref::<RuntimeException>()
+ .catch::<RuntimeException>()
.unwrap()
- .message
- .clone();
+ .get_message()
+ .to_string();
self.io.write_error3(
&format!("<error> Update failed ({})</error>", message),
true,
@@ -477,10 +468,10 @@ impl DownloadManager {
}
if sources.is_empty() {
- return Err(InvalidArgumentException {
- message: format!("Package {} must have a source or dist specified", package),
- code: 0,
- }
+ return Err(InvalidArgumentException::new(format!(
+ "Package {} must have a source or dist specified",
+ package
+ ))
.into());
}
diff --git a/crates/shirabe/src/downloader/file_downloader.rs b/crates/shirabe/src/downloader/file_downloader.rs
index cdcf750e..9b86ee56 100644
--- a/crates/shirabe/src/downloader/file_downloader.rs
+++ b/crates/shirabe/src/downloader/file_downloader.rs
@@ -25,6 +25,7 @@ use crate::util::Silencer;
use crate::util::Url as UrlUtil;
use crate::util::sync_executor;
use indexmap::IndexMap;
+use shirabe_php_shim::Catch as _;
use shirabe_php_shim::{
DIRECTORY_SEPARATOR, InvalidArgumentException, PATHINFO_BASENAME, PATHINFO_EXTENSION,
PHP_URL_PATH, PhpMixed, RuntimeException, UnexpectedValueException, array_search, file_exists,
@@ -359,11 +360,9 @@ impl FileDownloader {
url: &str,
) -> anyhow::Result<String> {
if !shirabe_php_shim::extension_loaded("openssl") && Some(0) == strpos(url, "https:") {
- return Err(RuntimeException {
- message: "You must enable the openssl extension to download files via https"
- .to_string(),
- code: 0,
- }
+ return Err(RuntimeException::new(
+ "You must enable the openssl extension to download files via https".to_string(),
+ )
.into());
}
@@ -400,10 +399,9 @@ impl DownloaderInterface for FileDownloader {
output: bool,
) -> anyhow::Result<Option<PhpMixed>> {
if package.get_dist_url().is_none() {
- return Err(InvalidArgumentException {
- message: "The given package is missing url information".to_string(),
- code: 0,
- }
+ return Err(InvalidArgumentException::new(
+ "The given package is missing url information".to_string(),
+ )
.into());
}
@@ -558,15 +556,15 @@ impl DownloaderInterface for FileDownloader {
}
self.clear_last_cache_write(package.clone());
- if e.downcast_ref::<IrrecoverableDownloadException>().is_some() {
+ if e.is_instanceof::<IrrecoverableDownloadException>() {
return Err(e);
}
- if e.downcast_ref::<MaxFileSizeExceededException>().is_some() {
+ if e.is_instanceof::<MaxFileSizeExceededException>() {
return Err(e);
}
- if let Some(te) = e.downcast_ref::<TransportException>() {
+ if let Some(te) = e.catch::<TransportException>() {
// if we got an http response with a proper code, then requesting again will probably not help, abort
if 0 != te.get_code() && !matches!(te.get_code(), 500 | 502 | 503 | 504)
{
@@ -592,7 +590,7 @@ impl DownloaderInterface for FileDownloader {
}
if !urls.is_empty() {
let code = e
- .downcast_ref::<TransportException>()
+ .catch::<TransportException>()
.map_or(0, |te| te.get_code());
if self.io.borrow().is_debug() {
self.io.borrow().write_error(&format!(
@@ -628,13 +626,10 @@ impl DownloaderInterface for FileDownloader {
// === $result->then(verify) ===
if !file_exists(&file_name) {
- return Err(UnexpectedValueException {
- message: format!(
- "{} could not be saved to {}, make sure the directory is writable and you have internet connectivity",
- url.base, file_name
- ),
- code: 0,
- }
+ return Err(UnexpectedValueException::new(format!(
+ "{} could not be saved to {}, make sure the directory is writable and you have internet connectivity",
+ url.base, file_name
+ ))
.into());
}
@@ -642,13 +637,10 @@ impl DownloaderInterface for FileDownloader {
&& !checksum.is_empty()
&& hash_file("sha1", &file_name).as_deref() != Some(checksum)
{
- return Err(UnexpectedValueException {
- message: format!(
- "The checksum verification of the file failed (downloaded from {})",
- url.base
- ),
- code: 0,
- }
+ return Err(UnexpectedValueException::new(format!(
+ "The checksum verification of the file failed (downloaded from {})",
+ url.base
+ ))
.into());
}
@@ -809,10 +801,10 @@ impl DownloaderInterface for FileDownloader {
}
let result = Filesystem::remove_directory_async_via(&self.filesystem, path).await?;
if !result {
- return Err(RuntimeException {
- message: format!("Could not completely delete {}, aborting.", path),
- code: 0,
- }
+ return Err(RuntimeException::new(format!(
+ "Could not completely delete {}, aborting.",
+ path
+ ))
.into());
}
diff --git a/crates/shirabe/src/downloader/filesystem_exception.rs b/crates/shirabe/src/downloader/filesystem_exception.rs
index f0aa831f..6e90e328 100644
--- a/crates/shirabe/src/downloader/filesystem_exception.rs
+++ b/crates/shirabe/src/downloader/filesystem_exception.rs
@@ -7,17 +7,15 @@ pub struct FilesystemException(pub Exception);
impl FilesystemException {
pub fn new(message: String, code: i64) -> Self {
- FilesystemException(Exception {
- message: format!("Filesystem exception: \n{}", message),
+ FilesystemException(Exception::with_code(
+ format!("Filesystem exception: \n{}", message),
code,
- })
+ ))
}
}
-impl std::fmt::Display for FilesystemException {
- fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
- self.0.fmt(f)
- }
-}
-
-impl std::error::Error for FilesystemException {}
+shirabe_php_shim::impl_php_exception!(
+ FilesystemException,
+ 0,
+ r"Composer\Downloader\FilesystemException"
+);
diff --git a/crates/shirabe/src/downloader/fossil_downloader.rs b/crates/shirabe/src/downloader/fossil_downloader.rs
index 72409a1f..86a44f0b 100644
--- a/crates/shirabe/src/downloader/fossil_downloader.rs
+++ b/crates/shirabe/src/downloader/fossil_downloader.rs
@@ -47,14 +47,11 @@ impl FossilDownloader {
.execute(&command, output, cwd.as_deref())?
!= 0
{
- return Err(RuntimeException {
- message: format!(
- "Failed to execute {}\n\n{}",
- command.join(" "),
- self.inner.process.borrow().get_error_output()
- ),
- code: 0,
- }
+ return Err(RuntimeException::new(format!(
+ "Failed to execute {}\n\n{}",
+ command.join(" "),
+ self.inner.process.borrow().get_error_output()
+ ))
.into());
}
Ok(())
@@ -168,13 +165,10 @@ impl VcsDownloader for FossilDownloader {
));
if !self.has_metadata_repository(path) {
- return Err(RuntimeException {
- message: format!(
- "The .fslckout file is missing from {}, see https://getcomposer.org/commit-deps for more information",
- path
- ),
- code: 0,
- }.into());
+ return Err(RuntimeException::new(format!(
+ "The .fslckout file is missing from {}, see https://getcomposer.org/commit-deps for more information",
+ path
+ )).into());
}
let real_path = shirabe_php_shim::realpath(path);
diff --git a/crates/shirabe/src/downloader/git_downloader.rs b/crates/shirabe/src/downloader/git_downloader.rs
index 275050fd..0a32d2fd 100644
--- a/crates/shirabe/src/downloader/git_downloader.rs
+++ b/crates/shirabe/src/downloader/git_downloader.rs
@@ -86,14 +86,11 @@ impl GitDownloader {
.execute_args(&command, &mut output, Some(&path))
!= 0
{
- return Err(RuntimeException {
- message: format!(
- "Failed to execute {}\n\n{}",
- implode(" ", &command),
- self.inner.process.borrow().get_error_output(),
- ),
- code: 0,
- }
+ return Err(RuntimeException::new(format!(
+ "Failed to execute {}\n\n{}",
+ implode(" ", &command),
+ self.inner.process.borrow().get_error_output(),
+ ))
.into());
}
@@ -186,14 +183,11 @@ impl GitDownloader {
Some(&path),
) != 0
{
- return Err(RuntimeException {
- message: format!(
- "Failed to execute {}\n\n{}",
- implode(" ", &command),
- self.inner.process.borrow().get_error_output(),
- ),
- code: 0,
- }
+ return Err(RuntimeException::new(format!(
+ "Failed to execute {}\n\n{}",
+ implode(" ", &command),
+ self.inner.process.borrow().get_error_output(),
+ ))
.into());
}
@@ -232,14 +226,11 @@ impl GitDownloader {
.execute_args(&command, &mut output, Some(&path))
!= 0
{
- return Err(RuntimeException {
- message: format!(
- "Failed to execute {}\n\n{}",
- implode(" ", &command),
- self.inner.process.borrow().get_error_output(),
- ),
- code: 0,
- }
+ return Err(RuntimeException::new(format!(
+ "Failed to execute {}\n\n{}",
+ implode(" ", &command),
+ self.inner.process.borrow().get_error_output(),
+ ))
.into());
}
refs = trim(&output, None);
@@ -486,15 +477,12 @@ impl GitDownloader {
let command = format!("{} && {}", implode(" ", &command1), implode(" ", &command2));
- Err(RuntimeException {
- message: Url::sanitize(format!(
- "Failed to execute {}\n\n{}{}",
- command,
- self.inner.process.borrow().get_error_output(),
- exception_extra,
- )),
- code: 0,
- }
+ Err(RuntimeException::new(Url::sanitize(format!(
+ "Failed to execute {}\n\n{}{}",
+ command,
+ self.inner.process.borrow().get_error_output(),
+ exception_extra,
+ )))
.into())
}
@@ -570,11 +558,9 @@ impl GitDownloader {
Some(&path),
) != 0
{
- return Err(RuntimeException {
- message: format!("Could not reset changes\n\n:{}", output),
- code: 0,
- }
- .into());
+ return Err(
+ RuntimeException::new(format!("Could not reset changes\n\n:{}", output)).into(),
+ );
}
let mut output = String::new();
if self.inner.process.borrow_mut().execute_args(
@@ -583,11 +569,9 @@ impl GitDownloader {
Some(&path),
) != 0
{
- return Err(RuntimeException {
- message: format!("Could not reset changes\n\n:{}", output),
- code: 0,
- }
- .into());
+ return Err(
+ RuntimeException::new(format!("Could not reset changes\n\n:{}", output)).into(),
+ );
}
self.has_discarded_changes.borrow_mut().insert(path, true);
@@ -609,11 +593,9 @@ impl GitDownloader {
Some(&path),
) != 0
{
- return Err(RuntimeException {
- message: format!("Could not stash changes\n\n:{}", output),
- code: 0,
- }
- .into());
+ return Err(
+ RuntimeException::new(format!("Could not stash changes\n\n:{}", output)).into(),
+ );
}
self.has_stashed_changes.borrow_mut().insert(path, true);
@@ -631,11 +613,9 @@ impl GitDownloader {
Some(&path),
) != 0
{
- return Err(RuntimeException {
- message: format!("Could not view diff\n\n:{}", output),
- code: 0,
- }
- .into());
+ return Err(
+ RuntimeException::new(format!("Could not view diff\n\n:{}", output)).into(),
+ );
}
self.inner
@@ -692,10 +672,10 @@ impl GitDownloader {
path: &str,
) -> anyhow::Result<()> {
if self.get_local_changes(package, path)?.is_some() {
- return Err(RuntimeException {
- message: format!("Source directory {} has uncommitted changes.", path),
- code: 0,
- }
+ return Err(RuntimeException::new(format!(
+ "Source directory {} has uncommitted changes.",
+ path
+ ))
.into());
}
@@ -738,14 +718,11 @@ impl ChangeReportInterface for GitDownloader {
.execute_args(&command, &mut output, Some(path))
!= 0
{
- return Err(RuntimeException {
- message: format!(
- "Failed to execute {}\n\n{}",
- implode(" ", &command),
- self.inner.process.borrow().get_error_output(),
- ),
- code: 0,
- }
+ return Err(RuntimeException::new(format!(
+ "Failed to execute {}\n\n{}",
+ implode(" ", &command),
+ self.inner.process.borrow().get_error_output(),
+ ))
.into());
}
@@ -848,10 +825,9 @@ impl VcsDownloader for GitDownloader {
.insert(r#ref.as_deref().unwrap_or("").to_string(), true);
}
} else if git_version.is_none() {
- return Err(RuntimeException {
- message: "git was not found in your PATH, skipping source download".to_string(),
- code: 0,
- }
+ return Err(RuntimeException::new(
+ "git was not found in your PATH, skipping source download".to_string(),
+ )
.into());
}
@@ -975,13 +951,10 @@ impl VcsDownloader for GitDownloader {
],
];
if Platform::get_env("COMPOSER_DISABLE_NETWORK").is_some() {
- return Err(RuntimeException {
- message: format!(
- "The required git reference for {} is not in cache and network is disabled, aborting",
- package.get_name(),
- ),
- code: 0,
- }
+ return Err(RuntimeException::new(format!(
+ "The required git reference for {} is not in cache and network is disabled, aborting",
+ package.get_name(),
+ ))
.into());
}
}
@@ -1022,13 +995,10 @@ impl VcsDownloader for GitDownloader {
GitUtil::clean_env(&self.inner.process);
let path = self.normalize_path(path);
if !self.has_metadata_repository(&path) {
- return Err(RuntimeException {
- message: format!(
- "The .git directory is missing from {}, see https://getcomposer.org/commit-deps for more information",
- path
- ),
- code: 0,
- }
+ return Err(RuntimeException::new(format!(
+ "The .git directory is missing from {}, see https://getcomposer.org/commit-deps for more information",
+ path
+ ))
.into());
}
@@ -1060,13 +1030,10 @@ impl VcsDownloader for GitDownloader {
msg = format!("Checking out {}", self.get_short_hash(&r#ref));
remote_url = "%url%".to_string();
if Platform::get_env("COMPOSER_DISABLE_NETWORK").is_some() {
- return Err(RuntimeException {
- message: format!(
- "The required git reference for {} is not in cache and network is disabled, aborting",
- target.get_name(),
- ),
- code: 0,
- }
+ return Err(RuntimeException::new(format!(
+ "The required git reference for {} is not in cache and network is disabled, aborting",
+ target.get_name(),
+ ))
.into());
}
}
@@ -1196,13 +1163,10 @@ impl VcsDownloader for GitDownloader {
.as_bool()
!= Some(true))
{
- return Err(RuntimeException {
- message: format!(
- "Source directory {} has unpushed changes on the current branch: \n{}",
- path, unpushed
- ),
- code: 0,
- }
+ return Err(RuntimeException::new(format!(
+ "Source directory {} has unpushed changes on the current branch: \n{}",
+ path, unpushed
+ ))
.into());
}
@@ -1285,11 +1249,7 @@ impl VcsDownloader for GitDownloader {
}
}
Some("n") => {
- return Err(RuntimeException {
- message: "Update aborted".to_string(),
- code: 0,
- }
- .into());
+ return Err(RuntimeException::new("Update aborted".to_string()).into());
}
Some("v") => {
self.inner
@@ -1362,13 +1322,10 @@ impl VcsDownloader for GitDownloader {
Some(&path),
) != 0
{
- return Err(RuntimeException {
- message: format!(
- "Failed to apply stashed changes:\n\n{}",
- self.inner.process.borrow().get_error_output()
- ),
- code: 0,
- }
+ return Err(RuntimeException::new(format!(
+ "Failed to apply stashed changes:\n\n{}",
+ self.inner.process.borrow().get_error_output()
+ ))
.into());
}
}
@@ -1399,14 +1356,11 @@ impl VcsDownloader for GitDownloader {
.execute_args(&command, &mut output, Some(&path))
!= 0
{
- return Err(RuntimeException {
- message: format!(
- "Failed to execute {}\n\n{}",
- implode(" ", &command),
- self.inner.process.borrow().get_error_output(),
- ),
- code: 0,
- }
+ return Err(RuntimeException::new(format!(
+ "Failed to execute {}\n\n{}",
+ implode(" ", &command),
+ self.inner.process.borrow().get_error_output(),
+ ))
.into());
}
diff --git a/crates/shirabe/src/downloader/gzip_downloader.rs b/crates/shirabe/src/downloader/gzip_downloader.rs
index b0494479..9473deff 100644
--- a/crates/shirabe/src/downloader/gzip_downloader.rs
+++ b/crates/shirabe/src/downloader/gzip_downloader.rs
@@ -127,10 +127,7 @@ impl ArchiveDownloader for GzipDownloader {
implode(" ", &command),
self.inner.process.borrow().get_error_output(),
);
- return Err(anyhow::anyhow!(RuntimeException {
- message: process_error,
- code: 0
- }));
+ return Err(RuntimeException::new(process_error).into());
}
self.extract_using_ext(file, &target_filepath);
diff --git a/crates/shirabe/src/downloader/hg_downloader.rs b/crates/shirabe/src/downloader/hg_downloader.rs
index e555ccf5..dfd25618 100644
--- a/crates/shirabe/src/downloader/hg_downloader.rs
+++ b/crates/shirabe/src/downloader/hg_downloader.rs
@@ -64,10 +64,9 @@ impl VcsDownloader for HgDownloader {
_prev_package: Option<PackageInterfaceHandle>,
) -> anyhow::Result<Option<PhpMixed>> {
if HgUtils::get_version(&self.inner.process).is_none() {
- return Err(RuntimeException {
- message: "hg was not found in your PATH, skipping source download".to_string(),
- code: 0,
- }
+ return Err(RuntimeException::new(
+ "hg was not found in your PATH, skipping source download".to_string(),
+ )
.into());
}
@@ -111,14 +110,11 @@ impl VcsDownloader for HgDownloader {
shirabe_php_shim::realpath(path).as_deref(),
) != 0
{
- return Err(RuntimeException {
- message: format!(
- "Failed to execute {}\n\n{}",
- command.join(" "),
- self.inner.process.borrow().get_error_output()
- ),
- code: 0,
- }
+ return Err(RuntimeException::new(format!(
+ "Failed to execute {}\n\n{}",
+ command.join(" "),
+ self.inner.process.borrow().get_error_output()
+ ))
.into());
}
@@ -145,13 +141,10 @@ impl VcsDownloader for HgDownloader {
));
if !self.has_metadata_repository(path) {
- return Err(RuntimeException {
- message: format!(
- "The .hg directory is missing from {}, see https://getcomposer.org/commit-deps for more information",
- path
- ),
- code: 0,
- }.into());
+ return Err(RuntimeException::new(format!(
+ "The .hg directory is missing from {}, see https://getcomposer.org/commit-deps for more information",
+ path
+ )).into());
}
let pull_command = |url: String| -> Vec<String> {
@@ -195,14 +188,11 @@ impl VcsDownloader for HgDownloader {
shirabe_php_shim::realpath(path).as_deref(),
) != 0
{
- return Err(RuntimeException {
- message: format!(
- "Failed to execute {}\n\n{}",
- command.join(" "),
- self.inner.process.borrow().get_error_output()
- ),
- code: 0,
- }
+ return Err(RuntimeException::new(format!(
+ "Failed to execute {}\n\n{}",
+ command.join(" "),
+ self.inner.process.borrow().get_error_output()
+ ))
.into());
}
diff --git a/crates/shirabe/src/downloader/max_file_size_exceeded_exception.rs b/crates/shirabe/src/downloader/max_file_size_exceeded_exception.rs
index ebec74df..7a730ff2 100644
--- a/crates/shirabe/src/downloader/max_file_size_exceeded_exception.rs
+++ b/crates/shirabe/src/downloader/max_file_size_exceeded_exception.rs
@@ -1,6 +1,6 @@
//! ref: composer/src/Composer/Downloader/MaxFileSizeExceededException.php
-use crate::downloader::TransportException;
+use crate::downloader::transport_exception::TransportException;
#[derive(Debug)]
pub struct MaxFileSizeExceededException(pub TransportException);
@@ -11,10 +11,8 @@ impl MaxFileSizeExceededException {
}
}
-impl std::fmt::Display for MaxFileSizeExceededException {
- fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
- self.0.fmt(f)
- }
-}
-
-impl std::error::Error for MaxFileSizeExceededException {}
+shirabe_php_shim::impl_php_exception!(
+ MaxFileSizeExceededException,
+ 0,
+ r"Composer\Downloader\MaxFileSizeExceededException"
+);
diff --git a/crates/shirabe/src/downloader/path_downloader.rs b/crates/shirabe/src/downloader/path_downloader.rs
index f10da72a..9449e74a 100644
--- a/crates/shirabe/src/downloader/path_downloader.rs
+++ b/crates/shirabe/src/downloader/path_downloader.rs
@@ -85,17 +85,14 @@ impl PathDownloader {
package: PackageInterfaceHandle,
path: &str,
) -> anyhow::Result<String> {
- let url = package.get_dist_url().ok_or_else(|| RuntimeException {
- message: format!(
+ let url = package.get_dist_url().ok_or_else(|| {
+ RuntimeException::new(format!(
"The package {} has no dist url configured, cannot install.",
package.get_pretty_name()
- ),
- code: 0,
- })?;
- let real_url = realpath(&url).ok_or_else(|| RuntimeException {
- message: format!("Failed to realpath {}", url),
- code: 0,
+ ))
})?;
+ let real_url = realpath(&url)
+ .ok_or_else(|| RuntimeException::new(format!("Failed to realpath {}", url)))?;
if realpath(path).as_deref() == Some(&real_url) {
return Ok(": Source already present".to_string());
@@ -157,10 +154,7 @@ impl PathDownloader {
&& !self.safe_junctions()
{
if !allowed_strategies.contains(&Self::STRATEGY_MIRROR) {
- return Err(RuntimeException {
- message: "You are on an old Windows / old PHP combo which does not allow Composer to use junctions/symlinks and this path repository has symlink:true in its options so copying is not allowed".to_string(),
- code: 0,
- }
+ return Err(RuntimeException::new("You are on an old Windows / old PHP combo which does not allow Composer to use junctions/symlinks and this path repository has symlink:true in its options so copying is not allowed".to_string())
.into());
}
current_strategy = Self::STRATEGY_MIRROR;
@@ -173,10 +167,7 @@ impl PathDownloader {
&& !function_exists("symlink")
{
if !allowed_strategies.contains(&Self::STRATEGY_MIRROR) {
- return Err(RuntimeException {
- message: "Your PHP has the symlink() function disabled which does not allow Composer to use symlinks and this path repository has symlink:true in its options so copying is not allowed".to_string(),
- code: 0,
- }
+ return Err(RuntimeException::new("Your PHP has the symlink() function disabled which does not allow Composer to use symlinks and this path repository has symlink:true in its options so copying is not allowed".to_string())
.into());
}
current_strategy = Self::STRATEGY_MIRROR;
@@ -243,26 +234,22 @@ impl DownloaderInterface for PathDownloader {
output: bool,
) -> anyhow::Result<Option<PhpMixed>> {
let path = Filesystem::trim_trailing_slash(path);
- let url = package.get_dist_url().ok_or_else(|| RuntimeException {
- message: format!(
+ let url = package.get_dist_url().ok_or_else(|| {
+ RuntimeException::new(format!(
"The package {} has no dist url configured, cannot download.",
package.get_pretty_name()
- ),
- code: 0,
+ ))
})?;
let real_url = realpath(&url);
if real_url.is_none()
|| !file_exists(real_url.as_deref().unwrap_or(""))
|| !is_dir(real_url.as_deref().unwrap_or(""))
{
- return Err(RuntimeException {
- message: format!(
- "Source path \"{}\" is not found for package {}",
- url,
- package.get_name()
- ),
- code: 0,
- }
+ return Err(RuntimeException::new(format!(
+ "Source path \"{}\" is not found for package {}",
+ url,
+ package.get_name()
+ ))
.into());
}
let real_url = real_url.unwrap();
@@ -282,15 +269,12 @@ impl DownloaderInterface for PathDownloader {
//
// Please see https://github.com/composer/composer/pull/5974 and https://github.com/composer/composer/pull/6174
// for previous attempts that were shut down because they did not work well enough or introduced too many risks.
- return Err(RuntimeException {
- message: format!(
- "Package {} cannot install to \"{}\" inside its source at \"{}\"",
- package.get_name(),
- realpath(&path).unwrap_or_default(),
- real_url
- ),
- code: 0,
- }
+ return Err(RuntimeException::new(format!(
+ "Package {} cannot install to \"{}\" inside its source at \"{}\"",
+ package.get_name(),
+ realpath(&path).unwrap_or_default(),
+ real_url
+ ))
.into());
}
@@ -316,17 +300,14 @@ impl DownloaderInterface for PathDownloader {
output: bool,
) -> anyhow::Result<Option<PhpMixed>> {
let path = Filesystem::trim_trailing_slash(path);
- let url = package.get_dist_url().ok_or_else(|| RuntimeException {
- message: format!(
+ let url = package.get_dist_url().ok_or_else(|| {
+ RuntimeException::new(format!(
"The package {} has no dist url configured, cannot install.",
package.get_pretty_name()
- ),
- code: 0,
- })?;
- let real_url = realpath(&url).ok_or_else(|| RuntimeException {
- message: format!("Failed to realpath {}", url),
- code: 0,
+ ))
})?;
+ let real_url = realpath(&url)
+ .ok_or_else(|| RuntimeException::new(format!("Failed to realpath {}", url)))?;
if realpath(&path).as_deref() == Some(&real_url) {
if output {
@@ -442,13 +423,10 @@ impl DownloaderInterface for PathDownloader {
current_strategy = Self::STRATEGY_MIRROR;
is_fallback = true;
} else {
- return Err(RuntimeException {
- message: format!(
- "Symlink from \"{}\" to \"{}\" failed!",
- real_url, path
- ),
- code: 0,
- }
+ return Err(RuntimeException::new(format!(
+ "Symlink from \"{}\" to \"{}\" failed!",
+ real_url, path
+ ))
.into());
}
}
@@ -537,25 +515,21 @@ impl DownloaderInterface for PathDownloader {
true,
io_interface::NORMAL,
);
- return Err(RuntimeException {
- message: format!(
- "Could not reliably remove junction for package {}",
- package.get_name()
- ),
- code: 0,
- }
+ return Err(RuntimeException::new(format!(
+ "Could not reliably remove junction for package {}",
+ package.get_name()
+ ))
.into());
}
return Ok(None);
}
- let url = package.get_dist_url().ok_or_else(|| RuntimeException {
- message: format!(
+ let url = package.get_dist_url().ok_or_else(|| {
+ RuntimeException::new(format!(
"The package {} has no dist url configured, cannot remove.",
package.get_pretty_name()
- ),
- code: 0,
+ ))
})?;
// ensure that the source path (dist url) is not the same as the install path, which
diff --git a/crates/shirabe/src/downloader/rar_downloader.rs b/crates/shirabe/src/downloader/rar_downloader.rs
index ee0148c7..f4f601bc 100644
--- a/crates/shirabe/src/downloader/rar_downloader.rs
+++ b/crates/shirabe/src/downloader/rar_downloader.rs
@@ -114,39 +114,30 @@ impl ArchiveDownloader for RarDownloader {
process_error.as_deref().unwrap_or(""),
)
};
- return Err(RuntimeException {
- message: error,
- code: 0,
- }
- .into());
+ return Err(RuntimeException::new(error).into());
}
let rar_archive = RarArchive::open(file);
if rar_archive.is_none() {
- return Err(UnexpectedValueException {
- message: format!("Could not open RAR archive: {}", file),
- code: 0,
- }
+ return Err(UnexpectedValueException::new(format!(
+ "Could not open RAR archive: {}",
+ file
+ ))
.into());
}
let rar_archive = rar_archive.unwrap();
let entries = rar_archive.get_entries();
if entries.is_none() {
- return Err(RuntimeException {
- message: "Could not retrieve RAR archive entries".to_string(),
- code: 0,
- }
+ return Err(RuntimeException::new(
+ "Could not retrieve RAR archive entries".to_string(),
+ )
.into());
}
for entry in entries.unwrap() {
if !entry.extract(path) {
- return Err(RuntimeException {
- message: "Could not extract entry".to_string(),
- code: 0,
- }
- .into());
+ return Err(RuntimeException::new("Could not extract entry".to_string()).into());
}
}
diff --git a/crates/shirabe/src/downloader/svn_downloader.rs b/crates/shirabe/src/downloader/svn_downloader.rs
index 6a8bdf0e..cb748a93 100644
--- a/crates/shirabe/src/downloader/svn_downloader.rs
+++ b/crates/shirabe/src/downloader/svn_downloader.rs
@@ -75,13 +75,10 @@ impl SvnDownloader {
Some(path),
) != 0
{
- return Err(RuntimeException {
- message: format!(
- "Could not reset changes\n\n:{}",
- self.inner.process.borrow().get_error_output()
- ),
- code: 0,
- }
+ return Err(RuntimeException::new(format!(
+ "Could not reset changes\n\n:{}",
+ self.inner.process.borrow().get_error_output()
+ ))
.into());
}
@@ -96,10 +93,10 @@ impl SvnDownloader {
path: &str,
) -> anyhow::Result<()> {
if self.get_local_changes(package, path)?.is_some() {
- return Err(RuntimeException {
- message: format!("Source directory {} has uncommitted changes.", path),
- code: 0,
- }
+ return Err(RuntimeException::new(format!(
+ "Source directory {} has uncommitted changes.",
+ path
+ ))
.into());
}
@@ -143,10 +140,9 @@ impl VcsDownloader for SvnDownloader {
Some(self.inner.process.clone()),
);
if util.binary_version().is_none() {
- return Err(RuntimeException {
- message: "svn was not found in your PATH, skipping source download".to_string(),
- code: 0,
- }
+ return Err(RuntimeException::new(
+ "svn was not found in your PATH, skipping source download".to_string(),
+ )
.into());
}
@@ -206,13 +202,10 @@ impl VcsDownloader for SvnDownloader {
let r#ref = target.get_source_reference();
if !self.has_metadata_repository(path) {
- return Err(RuntimeException {
- message: format!(
- "The .svn directory is missing from {}, see https://getcomposer.org/commit-deps for more information",
- path
- ),
- code: 0,
- }
+ return Err(RuntimeException::new(format!(
+ "The .svn directory is missing from {}, see https://getcomposer.org/commit-deps for more information",
+ path
+ ))
.into());
}
@@ -324,11 +317,7 @@ impl VcsDownloader for SvnDownloader {
break;
}
Some("n") => {
- return Err(RuntimeException {
- message: "Update aborted".to_string(),
- code: 0,
- }
- .into());
+ return Err(RuntimeException::new("Update aborted".to_string()).into());
}
Some("v") => {
for line in &changes {
@@ -384,14 +373,11 @@ impl VcsDownloader for SvnDownloader {
.execute_args(&command, &mut output, Some(path))
!= 0
{
- return Err(RuntimeException {
- message: format!(
- "Failed to execute {}\n\n{}",
- command.join(" "),
- self.inner.process.borrow().get_error_output()
- ),
- code: 0,
- }
+ return Err(RuntimeException::new(format!(
+ "Failed to execute {}\n\n{}",
+ command.join(" "),
+ self.inner.process.borrow().get_error_output()
+ ))
.into());
}
@@ -403,10 +389,10 @@ impl VcsDownloader for SvnDownloader {
.cloned()
.unwrap_or_default()
} else {
- return Err(RuntimeException {
- message: format!("Unable to determine svn url for path {}", path),
- code: 0,
- }
+ return Err(RuntimeException::new(format!(
+ "Unable to determine svn url for path {}",
+ path
+ ))
.into());
};
@@ -431,10 +417,11 @@ impl VcsDownloader for SvnDownloader {
util.set_cache_credentials(self.cache_credentials.get());
util.execute_local(command.clone(), path, None, self.inner.io.is_verbose())
.map_err(|e| {
- RuntimeException {
- message: format!("Failed to execute {}\n\n{}", command.join(" "), e),
- code: 0,
- }
+ RuntimeException::new(format!(
+ "Failed to execute {}\n\n{}",
+ command.join(" "),
+ e
+ ))
.into()
})
} else {
diff --git a/crates/shirabe/src/downloader/transport_exception.rs b/crates/shirabe/src/downloader/transport_exception.rs
index 155a5ce4..da8b4c50 100644
--- a/crates/shirabe/src/downloader/transport_exception.rs
+++ b/crates/shirabe/src/downloader/transport_exception.rs
@@ -1,11 +1,10 @@
//! ref: composer/src/Composer/Downloader/TransportException.php
-use shirabe_php_shim::PhpMixed;
+use shirabe_php_shim::{PhpMixed, RuntimeException};
#[derive(Debug, Clone)]
pub struct TransportException {
- pub message: String,
- pub code: i64,
+ inner: RuntimeException,
pub(crate) headers: Option<Vec<String>>,
pub(crate) response: Option<String>,
pub(crate) status_code: Option<i64>,
@@ -15,8 +14,7 @@ pub struct TransportException {
impl TransportException {
pub fn new(message: String, code: i64) -> Self {
Self {
- message,
- code,
+ inner: RuntimeException::with_code(message, code),
headers: None,
response: None,
status_code: None,
@@ -24,20 +22,6 @@ impl TransportException {
}
}
- /// PHP exposes ($message, $code = 0) — alias of `new` used at call sites where the
- /// status/exception code is provided up-front.
- pub fn new_with_code(message: String, code: i64) -> Self {
- Self::new(message, code)
- }
-
- pub fn get_code(&self) -> i64 {
- self.code
- }
-
- pub fn get_message(&self) -> &str {
- &self.message
- }
-
pub fn set_headers(&mut self, headers: Vec<String>) {
self.headers = Some(headers);
}
@@ -71,10 +55,8 @@ impl TransportException {
}
}
-impl std::fmt::Display for TransportException {
- fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
- write!(f, "{}", self.message)
- }
-}
-
-impl std::error::Error for TransportException {}
+shirabe_php_shim::impl_php_exception!(
+ TransportException,
+ inner,
+ r"Composer\Downloader\TransportException"
+);
diff --git a/crates/shirabe/src/downloader/vcs_downloader.rs b/crates/shirabe/src/downloader/vcs_downloader.rs
index 45ca0e3a..56bdea60 100644
--- a/crates/shirabe/src/downloader/vcs_downloader.rs
+++ b/crates/shirabe/src/downloader/vcs_downloader.rs
@@ -18,8 +18,9 @@ use crate::util::Filesystem;
use crate::util::ProcessExecutor;
use indexmap::IndexMap;
use shirabe_php_shim::{
- InvalidArgumentException, PhpMixed, RuntimeException, array_map, array_shift, explode,
- get_class_err, implode, rawurldecode, realpath, str_replace, strlen, strpos, substr, trim,
+ AnyThrowable, InvalidArgumentException, PhpClass as _, PhpMixed, RuntimeException, array_map,
+ array_shift, explode, implode, rawurldecode, realpath, str_replace, strlen, strpos, substr,
+ trim,
};
#[derive(Debug)]
@@ -129,13 +130,10 @@ pub trait VcsDownloader:
prev_package: Option<PackageInterfaceHandle>,
) -> anyhow::Result<Option<PhpMixed>> {
if package.get_source_reference().is_none() {
- return Err(InvalidArgumentException {
- message: format!(
- "Package {} is missing reference information",
- package.get_pretty_name(),
- ),
- code: 0,
- }
+ return Err(InvalidArgumentException::new(format!(
+ "Package {} is missing reference information",
+ package.get_pretty_name(),
+ ))
.into());
}
@@ -157,7 +155,13 @@ pub trait VcsDownloader:
}
if self.io().is_debug() {
self.io().write_error3(
- &format!("Failed: [{}] {}", get_class_err(&e), e),
+ &format!(
+ "Failed: [{}] {}",
+ AnyThrowable::of(e.as_ref())
+ .expect("PHP reaches this only with a caught \\Throwable")
+ .php_class_name(),
+ e
+ ),
true,
io_interface::NORMAL,
);
@@ -232,13 +236,10 @@ pub trait VcsDownloader:
path: &str,
) -> anyhow::Result<Option<PhpMixed>> {
if package.get_source_reference().is_none() {
- return Err(InvalidArgumentException {
- message: format!(
- "Package {} is missing reference information",
- package.get_pretty_name(),
- ),
- code: 0,
- }
+ return Err(InvalidArgumentException::new(format!(
+ "Package {} is missing reference information",
+ package.get_pretty_name(),
+ ))
.into());
}
@@ -264,7 +265,13 @@ pub trait VcsDownloader:
}
if self.io().is_debug() {
self.io().write_error3(
- &format!("Failed: [{}] {}", get_class_err(&e), e),
+ &format!(
+ "Failed: [{}] {}",
+ AnyThrowable::of(e.as_ref())
+ .expect("PHP reaches this only with a caught \\Throwable")
+ .php_class_name(),
+ e
+ ),
true,
io_interface::NORMAL,
);
@@ -292,13 +299,10 @@ pub trait VcsDownloader:
path: &str,
) -> anyhow::Result<Option<PhpMixed>> {
if target.get_source_reference().is_none() {
- return Err(InvalidArgumentException {
- message: format!(
- "Package {} is missing reference information",
- target.get_pretty_name(),
- ),
- code: 0,
- }
+ return Err(InvalidArgumentException::new(format!(
+ "Package {} is missing reference information",
+ target.get_pretty_name(),
+ ))
.into());
}
@@ -333,7 +337,13 @@ pub trait VcsDownloader:
}
if self.io().is_debug() {
self.io().write_error3(
- &format!("Failed: [{}] {}", get_class_err(&e), e),
+ &format!(
+ "Failed: [{}] {}",
+ AnyThrowable::of(e.as_ref())
+ .expect("PHP reaches this only with a caught \\Throwable")
+ .php_class_name(),
+ e
+ ),
true,
io_interface::NORMAL,
);
@@ -400,10 +410,10 @@ pub trait VcsDownloader:
let result = Filesystem::remove_directory_async_via(self.filesystem(), path).await?;
if !result {
- return Err(RuntimeException {
- message: format!("Could not completely delete {}, aborting.", path),
- code: 0,
- }
+ return Err(RuntimeException::new(format!(
+ "Could not completely delete {}, aborting.",
+ path
+ ))
.into());
}
@@ -441,10 +451,10 @@ pub trait VcsDownloader:
) -> anyhow::Result<Option<PhpMixed>> {
// the default implementation just fails if there are any changes, override in child classes to provide stash-ability
if self.get_local_changes(package, path)?.is_some() {
- return Err(RuntimeException {
- message: format!("Source directory {} has uncommitted changes.", path),
- code: 0,
- }
+ return Err(RuntimeException::new(format!(
+ "Source directory {} has uncommitted changes.",
+ path
+ ))
.into());
}
diff --git a/crates/shirabe/src/downloader/zip_downloader.rs b/crates/shirabe/src/downloader/zip_downloader.rs
index 8870194c..84ed4c9e 100644
--- a/crates/shirabe/src/downloader/zip_downloader.rs
+++ b/crates/shirabe/src/downloader/zip_downloader.rs
@@ -10,6 +10,7 @@ use crate::util::Platform;
use indexmap::IndexMap;
use shirabe_external_packages::composer::pcre::{CaptureKey, Preg};
use shirabe_external_packages::symfony::process::ExecutableFinder;
+use shirabe_php_shim::Catch as _;
use shirabe_php_shim::{
CmpOp, DIRECTORY_SEPARATOR, ErrorException, PhpMixed, RuntimeException,
UnexpectedValueException, ZipArchive, bin2hex, class_exists, file_exists, file_get_contents,
@@ -146,13 +147,10 @@ impl ZipDownloader {
.borrow()
.contains_key(&package.get_name())
{
- return Err(RuntimeException {
- message: format!(
- "Failed to extract {} as the installation was aborted by another package operation.",
- package.get_name()
- ),
- code: 0,
- }
+ return Err(RuntimeException::new(format!(
+ "Failed to extract {} as the installation was aborted by another package operation.",
+ package.get_name()
+ ))
.into());
}
@@ -162,19 +160,16 @@ impl ZipDownloader {
return self
.try_fallback(
- RuntimeException {
- message: format!(
- "Failed to extract {}: ({}) {}\n\n{}",
- package.get_name(),
- process
- .get_exit_code()
- .map(|c| c.to_string())
- .unwrap_or_default(),
- command.join(" "),
- output
- ),
- code: 0,
- }
+ RuntimeException::new(format!(
+ "Failed to extract {}: ({}) {}\n\n{}",
+ package.get_name(),
+ process
+ .get_exit_code()
+ .map(|c| c.to_string())
+ .unwrap_or_default(),
+ command.join(" "),
+ output
+ ))
.into(),
is_last_chance,
file,
@@ -337,13 +332,10 @@ impl ZipDownloader {
&& total_size > archive_sz * 100
&& total_size > 50 * 1024 * 1024
{
- return Err(RuntimeException {
- message: format!(
- "Invalid zip file for \"{}\" with compression ratio >99% (possible zip bomb)",
- package.get_name(),
- ),
- code: 0,
- }.into());
+ return Err(RuntimeException::new(format!(
+ "Invalid zip file for \"{}\" with compression ratio >99% (possible zip bomb)",
+ package.get_name(),
+ )).into());
}
}
@@ -354,32 +346,26 @@ impl ZipDownloader {
return Ok(None);
}
- Err(RuntimeException {
- message: format!(
- "There was an error extracting the ZIP file for \"{}\", it is either corrupted or using an invalid format.",
- package.get_name(),
- ),
- code: 0,
- }.into())
+ Err(RuntimeException::new(format!(
+ "There was an error extracting the ZIP file for \"{}\", it is either corrupted or using an invalid format.",
+ package.get_name(),
+ )).into())
}
- Err(code) => Err(UnexpectedValueException {
- message: self.get_error_message(code, file).trim_end().to_string(),
+ Err(code) => Err(UnexpectedValueException::with_code(
+ self.get_error_message(code, file).trim_end().to_string(),
code,
- }
+ )
.into()),
}
})();
result.map_err(|e| {
- if let Some(err) = e.downcast_ref::<ErrorException>() {
- RuntimeException {
- message: format!(
- "The archive for \"{}\" may contain identical file names with different capitalization (which fails on case insensitive filesystems): {}",
- package.get_name(),
- err.message,
- ),
- code: 0,
- }.into()
+ if let Some(err) = e.catch::<ErrorException>() {
+ RuntimeException::new(format!(
+ "The archive for \"{}\" may contain identical file names with different capitalization (which fails on case insensitive filesystems): {}",
+ package.get_name(),
+ err.get_message(),
+ )).into()
} else {
e
}
@@ -578,11 +564,7 @@ impl crate::downloader::DownloaderInterface for ZipDownloader {
ini_message
)
};
- return Err(RuntimeException {
- message: error,
- code: 0,
- }
- .into());
+ return Err(RuntimeException::new(error).into());
}
{
diff --git a/crates/shirabe/src/event_dispatcher/event_dispatcher.rs b/crates/shirabe/src/event_dispatcher/event_dispatcher.rs
index b821f647..3db924d4 100644
--- a/crates/shirabe/src/event_dispatcher/event_dispatcher.rs
+++ b/crates/shirabe/src/event_dispatcher/event_dispatcher.rs
@@ -29,6 +29,7 @@ use shirabe_php_rpc::{
PhpThrow, PluginValue, RustMethodDispatcher, RustObjHandle, call_function,
call_function_with_dispatcher, call_php_method, call_static_method,
};
+use shirabe_php_shim::Catch as _;
use shirabe_php_shim::{
InvalidArgumentException, PATH_SEPARATOR, PhpMixed, RuntimeException, array_pop, array_push,
array_search_in_vec, array_splice, file_exists, get_class, hash, implode, ini_get, is_array,
@@ -201,13 +202,9 @@ impl EventDispatcher {
) -> anyhow::Result<i64> {
match event {
None => {
- let name = event_name.ok_or_else(|| {
- anyhow::anyhow!(InvalidArgumentException {
- message:
- "If no $event is passed in to Composer\\EventDispatcher\\EventDispatcher::dispatch you have to pass in an $eventName, got null."
- .to_string(),
- code: 0,
- })
+ let name = event_name.ok_or_else(|| -> anyhow::Error {
+ InvalidArgumentException::new("If no $event is passed in to Composer\\EventDispatcher\\EventDispatcher::dispatch you have to pass in an $eventName, got null."
+ .to_string()).into()
})?;
let mut event = Event::new(name.to_string(), Vec::new(), IndexMap::new());
self.do_dispatch(&mut event)
@@ -411,15 +408,12 @@ impl EventDispatcher {
Some(&mut PluginRpcDispatcher::default()),
))?;
if !matches!(is_callable_value, PluginValue::Bool(true)) {
- return Err(anyhow::anyhow!(RuntimeException {
- message: format!(
- "Subscriber {}::{} for event {} is not callable, make sure the function is defined and public",
- handle.class,
- method_name,
- event.get_name()
- ),
- code: 0,
- }));
+ return Err(RuntimeException::new(format!(
+ "Subscriber {}::{} for event {} is not callable, make sure the function is defined and public",
+ handle.class,
+ method_name,
+ event.get_name()
+ )).into());
}
self.io.write_error3(
&format!(
@@ -431,18 +425,17 @@ impl EventDispatcher {
true,
crate::io::VERBOSE,
);
- let stub_class = Self::event_stub_class(event).ok_or_else(|| {
- // TODO(plugin): installer and plugin events have no proxy stub yet.
- anyhow::anyhow!(RuntimeException {
- message: format!(
- "no proxy stub is available yet for the event `{}` dispatched to {}::{}",
- event.get_name(),
- handle.class,
- method_name,
- ),
- code: 0,
- })
- })?;
+ let stub_class =
+ Self::event_stub_class(event).ok_or_else(|| -> anyhow::Error {
+ // TODO(plugin): installer and plugin events have no proxy stub yet.
+ RuntimeException::new(format!(
+ "no proxy stub is available yet for the event `{}` dispatched to {}::{}",
+ event.get_name(),
+ handle.class,
+ method_name,
+ ))
+ .into()
+ })?;
let event_rhandle = shirabe_php_rpc::alloc_rhandle();
let mut dispatcher = PluginRpcDispatcher {
event: Some((event_rhandle, event)),
@@ -469,10 +462,7 @@ impl EventDispatcher {
// TODO(plugin): the original exception class is collapsed to
// RuntimeException on this side of the boundary.
Err(throw) => {
- return Err(anyhow::anyhow!(RuntimeException {
- message: throw.message,
- code: throw.code,
- }));
+ return Err(RuntimeException::with_code(throw.message, throw.code).into());
}
};
} else if !is_string_callable {
@@ -494,15 +484,12 @@ impl EventDispatcher {
}
_ => ("?".to_string(), "?".to_string()),
};
- return Err(anyhow::anyhow!(RuntimeException {
- message: format!(
- "Subscriber {}::{} for event {} is not callable, make sure the function is defined and public",
- class_name,
- method,
- event.get_name()
- ),
- code: 0,
- }));
+ return Err(RuntimeException::new(format!(
+ "Subscriber {}::{} for event {} is not callable, make sure the function is defined and public",
+ class_name,
+ method,
+ event.get_name()
+ )).into());
}
if let Callable::ArrayCallable(first, method_name) = &callable {
let prefix = if is_object(first.as_ref()) {
@@ -594,15 +581,14 @@ impl EventDispatcher {
exit_code
), true, crate::io::QUIET);
- return Err(anyhow::anyhow!(ScriptExecutionException(
- RuntimeException {
- message: format!(
- "Error Output: {}",
- self.process.borrow().get_error_output()
- ),
- code: exit_code,
- }
- )));
+ return Err(ScriptExecutionException::new(
+ format!(
+ "Error Output: {}",
+ self.process.borrow().get_error_output()
+ ),
+ exit_code,
+ )
+ .into());
}
} else {
if self
@@ -638,7 +624,7 @@ impl EventDispatcher {
match self.dispatch(Some(&script_name), Some(&mut script_event)) {
Ok(v) => r#return = v,
Err(e) => {
- if e.downcast_ref::<ScriptExecutionException>().is_some() {
+ if e.is_instanceof::<ScriptExecutionException>() {
self.io.write_error3(
&format!(
"<error>Script {} was called via {}</error>",
@@ -839,10 +825,9 @@ try {{
true,
crate::io::QUIET,
);
- return Err(anyhow::anyhow!(RuntimeException {
- message: throw.message,
- code: throw.code,
- }));
+ return Err(
+ RuntimeException::with_code(throw.message, throw.code).into()
+ );
}
};
let command_output = result
@@ -876,7 +861,7 @@ try {{
true,
crate::io::QUIET,
);
- return Err(anyhow::anyhow!(RuntimeException { message, code }));
+ return Err(RuntimeException::with_code(message, code).into());
}
r#return = match result.as_array().and_then(|map| map.get("status")) {
Some(PhpMixed::Int(status)) => *status,
@@ -1043,15 +1028,14 @@ try {{
exit_code
), true, crate::io::QUIET);
- return Err(anyhow::anyhow!(ScriptExecutionException(
- RuntimeException {
- message: format!(
- "Error Output: {}",
- self.process.borrow().get_error_output()
- ),
- code: exit_code,
- }
- )));
+ return Err(ScriptExecutionException::new(
+ format!(
+ "Error Output: {}",
+ self.process.borrow().get_error_output()
+ ),
+ exit_code,
+ )
+ .into());
}
}
_ => {
@@ -1097,10 +1081,10 @@ try {{
let php_path = match php_path {
Some(p) => p,
None => {
- return Err(anyhow::anyhow!(RuntimeException {
- message: "Failed to locate PHP binary to execute ".to_string(),
- code: 0,
- }));
+ return Err(RuntimeException::new(
+ "Failed to locate PHP binary to execute ".to_string(),
+ )
+ .into());
}
};
let php_args = finder.find_arguments();
@@ -1152,17 +1136,15 @@ try {{
);
}
- let stub_class = Self::event_stub_class(event).ok_or_else(|| {
+ let stub_class = Self::event_stub_class(event).ok_or_else(|| -> anyhow::Error {
// TODO(plugin): installer and plugin events have no proxy stub yet.
- anyhow::anyhow!(RuntimeException {
- message: format!(
- "no proxy stub is available yet for the event `{}` dispatched to {}::{}",
- event.get_name(),
- class_name,
- method_name,
- ),
- code: 0,
- })
+ RuntimeException::new(format!(
+ "no proxy stub is available yet for the event `{}` dispatched to {}::{}",
+ event.get_name(),
+ class_name,
+ method_name,
+ ))
+ .into()
})?;
Self::ensure_script_autoloader()?;
@@ -1186,10 +1168,7 @@ try {{
Ok(value) => Ok(value.to_php_mixed()?),
// TODO(plugin): the original exception class is collapsed to RuntimeException on
// this side of the boundary.
- Err(throw) => Err(anyhow::anyhow!(RuntimeException {
- message: throw.message,
- code: throw.code,
- })),
+ Err(throw) => Err(RuntimeException::with_code(throw.message, throw.code).into()),
}
}
@@ -1395,13 +1374,11 @@ try {{
fn push_event(&mut self, event: &dyn EventInterface) -> anyhow::Result<i64> {
let event_name = event.get_name().to_string();
if self.event_stack.iter().any(|n| n == &event_name) {
- return Err(anyhow::anyhow!(RuntimeException {
- message: format!(
- "Circular call to script handler '{}' detected",
- PhpMixed::String(event_name),
- ),
- code: 0,
- }));
+ return Err(RuntimeException::new(format!(
+ "Circular call to script handler '{}' detected",
+ PhpMixed::String(event_name),
+ ))
+ .into());
}
Ok(array_push(&mut self.event_stack, event_name))
@@ -1597,13 +1574,13 @@ try {{
pub(crate) fn ensure_composer_php_runtime() -> anyhow::Result<()> {
// TODO(plugin): the real PHP classes are taken from a Composer checkout for now; how
// they ship with a released Shirabe binary is part of the plugin distribution work.
- let autoload = Self::composer_php_runtime_autoload().ok_or_else(|| {
- anyhow::anyhow!(RuntimeException {
- message: "unable to locate the Composer PHP runtime; set SHIRABE_COMPOSER_PHP_DIR \
+ let autoload = Self::composer_php_runtime_autoload().ok_or_else(|| -> anyhow::Error {
+ RuntimeException::new(
+ "unable to locate the Composer PHP runtime; set SHIRABE_COMPOSER_PHP_DIR \
to a Composer checkout with its vendor directory installed"
.to_string(),
- code: 0,
- })
+ )
+ .into()
})?;
unwrap_php_result(call_function(
"__shirabe_require",
@@ -1857,10 +1834,7 @@ pub(crate) fn unwrap_php_result(
) -> anyhow::Result<PluginValue> {
match outcome? {
Ok(value) => Ok(value),
- Err(throw) => Err(anyhow::anyhow!(RuntimeException {
- message: throw.message,
- code: throw.code,
- })),
+ Err(throw) => Err(RuntimeException::with_code(throw.message, throw.code).into()),
}
}
diff --git a/crates/shirabe/src/event_dispatcher/script_execution_exception.rs b/crates/shirabe/src/event_dispatcher/script_execution_exception.rs
index 05567b01..e4ce1ec0 100644
--- a/crates/shirabe/src/event_dispatcher/script_execution_exception.rs
+++ b/crates/shirabe/src/event_dispatcher/script_execution_exception.rs
@@ -7,19 +7,13 @@ use shirabe_php_shim::RuntimeException;
pub struct ScriptExecutionException(pub RuntimeException);
impl ScriptExecutionException {
- pub fn get_code(&self) -> i64 {
- self.0.code
- }
-
- pub fn get_message(&self) -> &str {
- &self.0.message
- }
-}
-
-impl std::fmt::Display for ScriptExecutionException {
- fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
- self.0.fmt(f)
+ pub fn new(message: String, code: i64) -> Self {
+ Self(RuntimeException::with_code(message, code))
}
}
-impl std::error::Error for ScriptExecutionException {}
+shirabe_php_shim::impl_php_exception!(
+ ScriptExecutionException,
+ 0,
+ r"Composer\EventDispatcher\ScriptExecutionException"
+);
diff --git a/crates/shirabe/src/exception/irrecoverable_download_exception.rs b/crates/shirabe/src/exception/irrecoverable_download_exception.rs
index a8d2dbb4..ed424eff 100644
--- a/crates/shirabe/src/exception/irrecoverable_download_exception.rs
+++ b/crates/shirabe/src/exception/irrecoverable_download_exception.rs
@@ -5,10 +5,14 @@ use shirabe_php_shim::RuntimeException;
#[derive(Debug)]
pub struct IrrecoverableDownloadException(pub RuntimeException);
-impl std::fmt::Display for IrrecoverableDownloadException {
- fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
- self.0.fmt(f)
+impl IrrecoverableDownloadException {
+ pub fn new(message: String) -> Self {
+ Self(RuntimeException::new(message))
}
}
-impl std::error::Error for IrrecoverableDownloadException {}
+shirabe_php_shim::impl_php_exception!(
+ IrrecoverableDownloadException,
+ 0,
+ r"Composer\Exception\IrrecoverableDownloadException"
+);
diff --git a/crates/shirabe/src/exception/no_ssl_exception.rs b/crates/shirabe/src/exception/no_ssl_exception.rs
index 968ecfd7..b0470e58 100644
--- a/crates/shirabe/src/exception/no_ssl_exception.rs
+++ b/crates/shirabe/src/exception/no_ssl_exception.rs
@@ -6,10 +6,10 @@ use shirabe_php_shim::RuntimeException;
#[derive(Debug)]
pub struct NoSslException(pub RuntimeException);
-impl std::fmt::Display for NoSslException {
- fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
- self.0.fmt(f)
+impl NoSslException {
+ pub fn new(message: String) -> Self {
+ Self(RuntimeException::new(message))
}
}
-impl std::error::Error for NoSslException {}
+shirabe_php_shim::impl_php_exception!(NoSslException, 0, r"Composer\Exception\NoSslException");
diff --git a/crates/shirabe/src/factory.rs b/crates/shirabe/src/factory.rs
index 7328bf42..d7439d58 100644
--- a/crates/shirabe/src/factory.rs
+++ b/crates/shirabe/src/factory.rs
@@ -55,6 +55,7 @@ use shirabe_external_packages::symfony::console::formatter::OutputFormatter;
use shirabe_external_packages::symfony::console::formatter::OutputFormatterStyle;
use shirabe_external_packages::symfony::console::formatter::OutputFormatterStyleInterface;
use shirabe_external_packages::symfony::console::output::ConsoleOutput;
+use shirabe_php_shim::Catch as _;
use shirabe_php_shim::{
InvalidArgumentException, PATHINFO_EXTENSION, PHP_EOL, PHP_OS, PhpMixed, RuntimeException,
UnexpectedValueException, array_replace_recursive, class_exists, dirname, extension_loaded,
@@ -105,12 +106,8 @@ impl Factory {
.map(|s| s.is_empty())
.unwrap_or(true)
{
- return Err(anyhow::anyhow!(RuntimeException {
- message:
- "The APPDATA or COMPOSER_HOME environment variable must be set for composer to run correctly"
- .to_string(),
- code: 0,
- }));
+ return Err(RuntimeException::new("The APPDATA or COMPOSER_HOME environment variable must be set for composer to run correctly"
+ .to_string()).into());
}
let appdata = Platform::get_env("APPDATA").unwrap_or_default();
@@ -358,13 +355,10 @@ impl Factory {
let env_trimmed = trim(&env_str, Some(" \t\n\r\0\u{0B}"));
if !env_trimmed.is_empty() {
if is_dir(&env_trimmed) {
- return Err(anyhow::anyhow!(RuntimeException {
- message: format!(
- "The COMPOSER environment variable is set to {} which is a directory, this variable should point to a composer.json or be left unset.",
- env_trimmed
- ),
- code: 0,
- }));
+ return Err(RuntimeException::new(format!(
+ "The COMPOSER environment variable is set to {} which is a directory, this variable should point to a composer.json or be left unset.",
+ env_trimmed
+ )).into());
}
return Ok(env_trimmed);
@@ -465,25 +459,25 @@ impl Factory {
} else {
""
};
- return Err(anyhow::anyhow!(InvalidArgumentException {
- message: format!("{}{}{}", message, PHP_EOL, instructions),
- code: 0,
- }));
+ return Err(InvalidArgumentException::new(format!(
+ "{}{}{}",
+ message, PHP_EOL, instructions
+ ))
+ .into());
}
if !Platform::is_input_completion_process()
&& let Err(e) = file.validate_schema(JsonFile::LAX_SCHEMA, None)
{
- if let Some(jve) = e.downcast_ref::<JsonValidationException>() {
+ if let Some(jve) = e.catch::<JsonValidationException>() {
let errors = format!(
" - {}",
implode(&format!("{} - ", PHP_EOL), jve.get_errors())
);
let message = format!("{}:{}{}", jve.get_message(), PHP_EOL, errors);
- return Err(anyhow::anyhow!(JsonValidationException::new(
- message,
- jve.get_errors().clone(),
- )));
+ return Err(
+ JsonValidationException::new(message, jve.get_errors().clone()).into(),
+ );
}
return Err(e);
}
@@ -1358,10 +1352,7 @@ impl Factory {
factory.create_composer(io, config, disable_plugins, None, true, disable_scripts)?;
// fullLoad=true guarantees a full Composer; narrow PartialComposer -> Composer (PHP `: Composer`).
composer.as_full().ok_or_else(|| {
- anyhow::anyhow!(RuntimeException {
- message: "Composer expected with fullLoad=true".to_string(),
- code: 0,
- })
+ RuntimeException::new("Composer expected with fullLoad=true".to_string()).into()
})
}
@@ -1394,10 +1385,7 @@ impl Factory {
let composer =
factory.create_composer(io, config, disable_plugins, None, true, disable_scripts)?;
composer.as_full().ok_or_else(|| {
- anyhow::anyhow!(RuntimeException {
- message: "Composer expected with fullLoad=true".to_string(),
- code: 0,
- })
+ RuntimeException::new("Composer expected with fullLoad=true".to_string()).into()
})
}
@@ -1465,12 +1453,8 @@ impl Factory {
unsafe { WARNED = true };
disable_tls = true;
} else if !extension_loaded("openssl") {
- return Err(anyhow::anyhow!(NoSslException(RuntimeException {
- message:
- "The openssl extension is required for SSL/TLS protection but is not available. If you can not enable the openssl extension, you can disable this error, at your own risk, by setting the 'disable-tls' option to true."
- .to_string(),
- code: 0,
- })));
+ return Err(NoSslException::new("The openssl extension is required for SSL/TLS protection but is not available. If you can not enable the openssl extension, you can disable this error, at your own risk, by setting the 'disable-tls' option to true."
+ .to_string()).into());
}
let mut http_downloader_options: IndexMap<String, PhpMixed> = IndexMap::new();
if !disable_tls {
@@ -1509,7 +1493,7 @@ impl Factory {
let http_downloader = match http_downloader_result {
Ok(h) => h,
Err(e) => {
- if let Some(te) = e.downcast_ref::<TransportException>()
+ if let Some(te) = e.catch::<TransportException>()
&& strpos(te.get_message(), "cafile").is_some()
{
io.write3(
@@ -1547,12 +1531,11 @@ impl Factory {
let auth_data = json_decode(&composer_auth_env_str, false)?;
if matches!(auth_data, PhpMixed::Null) {
- return Err(anyhow::anyhow!(UnexpectedValueException {
- message:
- "COMPOSER_AUTH environment variable is malformed, should be a valid JSON object"
- .to_string(),
- code: 0,
- }));
+ return Err(UnexpectedValueException::new(
+ "COMPOSER_AUTH environment variable is malformed, should be a valid JSON object"
+ .to_string(),
+ )
+ .into());
}
if let Some(io_ref) = &io {
@@ -1591,12 +1574,8 @@ impl Factory {
fn get_user_dir() -> anyhow::Result<String> {
let home = Platform::get_env("HOME").unwrap_or_default();
if home.is_empty() {
- return Err(anyhow::anyhow!(RuntimeException {
- message:
- "The HOME or COMPOSER_HOME environment variable must be set for composer to run correctly"
- .to_string(),
- code: 0,
- }));
+ return Err(RuntimeException::new("The HOME or COMPOSER_HOME environment variable must be set for composer to run correctly"
+ .to_string()).into());
}
Ok(trim(&strtr(&home, "\\", "/"), Some("/")))
@@ -1615,20 +1594,19 @@ impl Factory {
let result = match file_or_data {
ValidateJsonInput::File(file) => file.validate_schema(schema, None),
ValidateJsonInput::Data(data) => {
- let source = source.ok_or_else(|| {
- anyhow::anyhow!(InvalidArgumentException {
- message:
- "$source is required to be provided if $fileOrData is arbitrary data"
- .to_string(),
- code: 0,
- })
+ let source = source.ok_or_else(|| -> anyhow::Error {
+ InvalidArgumentException::new(
+ "$source is required to be provided if $fileOrData is arbitrary data"
+ .to_string(),
+ )
+ .into()
})?;
JsonFile::validate_json_schema(source, &data, schema, None)
}
};
if let Err(e) = result {
- if let Some(jve) = e.downcast_ref::<JsonValidationException>() {
+ if let Some(jve) = e.catch::<JsonValidationException>() {
let msg = format!(
"{}, this may result in errors and should be resolved:{} - {}",
jve.get_message(),
@@ -1638,10 +1616,7 @@ impl Factory {
if let Some(io_ref) = io {
io_ref.write_error3(&format!("<warning>{}</>", msg), true, crate::io::NORMAL);
} else {
- return Err(anyhow::anyhow!(UnexpectedValueException {
- message: msg,
- code: 0
- }));
+ return Err(UnexpectedValueException::new(msg).into());
}
} else {
return Err(e);
diff --git a/crates/shirabe/src/filter/platform_requirement_filter/platform_requirement_filter_factory.rs b/crates/shirabe/src/filter/platform_requirement_filter/platform_requirement_filter_factory.rs
index 12c69091..7f08e8dd 100644
--- a/crates/shirabe/src/filter/platform_requirement_filter/platform_requirement_filter_factory.rs
+++ b/crates/shirabe/src/filter/platform_requirement_filter/platform_requirement_filter_factory.rs
@@ -38,13 +38,10 @@ impl PlatformRequirementFilterFactory {
list,
)?))
}
- other => Err(anyhow::anyhow!(InvalidArgumentException {
- message: format!(
- "PlatformRequirementFilter: Unknown $boolOrList parameter {}. Please report at https://github.com/composer/composer/issues/new.",
- shirabe_php_shim::get_debug_type(&other)
- ),
- code: 0,
- })),
+ other => Err(InvalidArgumentException::new(format!(
+ "PlatformRequirementFilter: Unknown $boolOrList parameter {}. Please report at https://github.com/composer/composer/issues/new.",
+ shirabe_php_shim::get_debug_type(&other)
+ )).into()),
}
}
diff --git a/crates/shirabe/src/installed_versions.rs b/crates/shirabe/src/installed_versions.rs
index ce78f013..6d702413 100644
--- a/crates/shirabe/src/installed_versions.rs
+++ b/crates/shirabe/src/installed_versions.rs
@@ -202,11 +202,10 @@ impl InstalledVersions {
return Ok(implode(" || ", &ranges));
}
- Err(OutOfBoundsException {
- message: format!("Package \"{}\" is not installed", package_name),
- code: 0,
- }
- .into())
+ Err(
+ OutOfBoundsException::new(format!("Package \"{}\" is not installed", package_name))
+ .into(),
+ )
}
/// @return string|null If the package is being replaced or provided but is not really installed, null will be returned as version, use satisfies or getVersionRanges if you need to know if a given version is present
@@ -229,11 +228,10 @@ impl InstalledVersions {
.map(|s| s.to_string()));
}
- Err(OutOfBoundsException {
- message: format!("Package \"{}\" is not installed", package_name),
- code: 0,
- }
- .into())
+ Err(
+ OutOfBoundsException::new(format!("Package \"{}\" is not installed", package_name))
+ .into(),
+ )
}
/// @return string|null If the package is being replaced or provided but is not really installed, null will be returned as version, use satisfies or getVersionRanges if you need to know if a given version is present
@@ -256,11 +254,10 @@ impl InstalledVersions {
.map(|s| s.to_string()));
}
- Err(OutOfBoundsException {
- message: format!("Package \"{}\" is not installed", package_name),
- code: 0,
- }
- .into())
+ Err(
+ OutOfBoundsException::new(format!("Package \"{}\" is not installed", package_name))
+ .into(),
+ )
}
/// @return string|null If the package is being replaced or provided but is not really installed, null will be returned as reference
@@ -283,11 +280,10 @@ impl InstalledVersions {
.map(|s| s.to_string()));
}
- Err(OutOfBoundsException {
- message: format!("Package \"{}\" is not installed", package_name),
- code: 0,
- }
- .into())
+ Err(
+ OutOfBoundsException::new(format!("Package \"{}\" is not installed", package_name))
+ .into(),
+ )
}
/// @return string|null If the package is being replaced or provided but is not really installed, null will be returned as install path. Packages of type metapackages also have a null install path.
@@ -309,11 +305,10 @@ impl InstalledVersions {
});
}
- Err(OutOfBoundsException {
- message: format!("Package \"{}\" is not installed", package_name),
- code: 0,
- }
- .into())
+ Err(
+ OutOfBoundsException::new(format!("Package \"{}\" is not installed", package_name))
+ .into(),
+ )
}
pub fn get_root_package() -> IndexMap<String, PhpMixed> {
diff --git a/crates/shirabe/src/installer.rs b/crates/shirabe/src/installer.rs
index 9028af88..702569aa 100644
--- a/crates/shirabe/src/installer.rs
+++ b/crates/shirabe/src/installer.rs
@@ -28,6 +28,7 @@ pub use package_event::*;
pub use package_events::*;
pub use plugin_installer::*;
pub use project_installer::*;
+use shirabe_php_shim::Catch as _;
pub use suggested_packages_reporter::*;
use crate::io::io_interface;
@@ -226,10 +227,11 @@ impl Installer {
gc_disable();
if self.update_allow_list.is_some() && self.update_mirrors {
- return Err(RuntimeException {
- message: "The installer options updateMirrors and updateAllowList are mutually exclusive.".to_string(),
- code: 0,
- }.into());
+ return Err(RuntimeException::new(
+ "The installer options updateMirrors and updateAllowList are mutually exclusive."
+ .to_string(),
+ )
+ .into());
}
let is_fresh_install = self
@@ -535,7 +537,7 @@ impl Installer {
});
}
Err(e) => {
- if let Some(te) = e.downcast_ref::<TransportException>() {
+ if let Some(te) = e.catch::<TransportException>() {
self.io
.error(&format!("Failed to audit {} packages.", target), &[]);
if self.io.is_verbose() {
@@ -570,27 +572,25 @@ impl Installer {
let mut locked_repository: Option<crate::repository::LockArrayRepositoryHandle> = None;
let try_load_locked = || -> anyhow::Result<
- Result<Option<crate::repository::LockArrayRepositoryHandle>, ParsingException>,
+ Result<Option<crate::repository::LockArrayRepositoryHandle>, anyhow::Error>,
> {
- if self.locker.borrow_mut().is_locked() {
- match self.locker.borrow_mut().get_locked_repository(true) {
- Ok(r) => Ok(Ok(Some(r))),
- Err(e) => match e.downcast::<ParsingException>() {
- Ok(p) => Ok(Err(p)),
- Err(other) => Err(other),
- },
- }
- } else {
- Ok(Ok(None))
+ if self.locker.borrow_mut().is_locked() {
+ match self.locker.borrow_mut().get_locked_repository(true) {
+ Ok(r) => Ok(Ok(Some(r))),
+ Err(e) if e.is_instanceof::<ParsingException>() => Ok(Err(e)),
+ Err(e) => Err(e),
}
- };
+ } else {
+ Ok(Ok(None))
+ }
+ };
match try_load_locked()? {
Ok(r) => locked_repository = r,
Err(e) => {
if self.update_allow_list.is_some() || self.update_mirrors {
// in case we are doing a partial update or updating mirrors, the lock file is needed so we error
- return Err(e.into());
+ return Err(e);
}
// otherwise, ignoring parse errors as the lock file will be regenerated from scratch when
// doing a full update
diff --git a/crates/shirabe/src/installer/installation_manager.rs b/crates/shirabe/src/installer/installation_manager.rs
index 1f1c60a5..454dfa86 100644
--- a/crates/shirabe/src/installer/installation_manager.rs
+++ b/crates/shirabe/src/installer/installation_manager.rs
@@ -191,11 +191,7 @@ impl InstallationManager {
}
}
- Err(InvalidArgumentException {
- message: format!("Unknown installer type: {}", r#type),
- code: 0,
- }
- .into())
+ Err(InvalidArgumentException::new(format!("Unknown installer type: {}", r#type)).into())
}
/// Checks whether provided package is installed in one of the registered installers.
diff --git a/crates/shirabe/src/installer/library_installer.rs b/crates/shirabe/src/installer/library_installer.rs
index e53b9546..6c94e0c1 100644
--- a/crates/shirabe/src/installer/library_installer.rs
+++ b/crates/shirabe/src/installer/library_installer.rs
@@ -210,14 +210,11 @@ impl LibraryInstaller {
assert!(
self.download_manager.is_some(),
"{}",
- LogicException {
- message: format!(
+ LogicException::new(format!(
"{} should be initialized with a fully loaded Composer instance to be able to install/... packages",
"LibraryInstaller",
- ),
- code: 0,
- }
- .message
+ ))
+ .get_message()
);
self.download_manager.as_ref().unwrap()
@@ -345,10 +342,10 @@ impl InstallerInterface for LibraryInstaller {
target: PackageInterfaceHandle,
) -> anyhow::Result<Option<PhpMixed>> {
if !repo.borrow_mut().has_package(initial.clone())? {
- return Err(InvalidArgumentException {
- message: format!("Package is not installed: {}", initial),
- code: 0,
- }
+ return Err(InvalidArgumentException::new(format!(
+ "Package is not installed: {}",
+ initial
+ ))
.into());
}
@@ -378,10 +375,10 @@ impl InstallerInterface for LibraryInstaller {
package: PackageInterfaceHandle,
) -> anyhow::Result<Option<PhpMixed>> {
if !repo.borrow_mut().has_package(package.clone())? {
- return Err(InvalidArgumentException {
- message: format!("Package is not installed: {}", package),
- code: 0,
- }
+ return Err(InvalidArgumentException::new(format!(
+ "Package is not installed: {}",
+ package
+ ))
.into());
}
diff --git a/crates/shirabe/src/installer/metapackage_installer.rs b/crates/shirabe/src/installer/metapackage_installer.rs
index 52c152ea..99d3786c 100644
--- a/crates/shirabe/src/installer/metapackage_installer.rs
+++ b/crates/shirabe/src/installer/metapackage_installer.rs
@@ -86,10 +86,10 @@ impl InstallerInterface for MetapackageInstaller {
target: PackageInterfaceHandle,
) -> anyhow::Result<Option<PhpMixed>> {
if !repo.borrow_mut().has_package(initial.clone())? {
- return Err(InvalidArgumentException {
- message: format!("Package is not installed: {}", initial),
- code: 0,
- }
+ return Err(InvalidArgumentException::new(format!(
+ "Package is not installed: {}",
+ initial
+ ))
.into());
}
@@ -115,10 +115,10 @@ impl InstallerInterface for MetapackageInstaller {
package: PackageInterfaceHandle,
) -> anyhow::Result<Option<PhpMixed>> {
if !repo.borrow_mut().has_package(package.clone())? {
- return Err(InvalidArgumentException {
- message: format!("Package is not installed: {}", package),
- code: 0,
- }
+ return Err(InvalidArgumentException::new(format!(
+ "Package is not installed: {}",
+ package
+ ))
.into());
}
diff --git a/crates/shirabe/src/installer/noop_installer.rs b/crates/shirabe/src/installer/noop_installer.rs
index 95f31f2e..d36f5c9e 100644
--- a/crates/shirabe/src/installer/noop_installer.rs
+++ b/crates/shirabe/src/installer/noop_installer.rs
@@ -69,10 +69,10 @@ impl InstallerInterface for NoopInstaller {
) -> anyhow::Result<Option<PhpMixed>> {
let mut repo = repo.borrow_mut();
if !repo.has_package(initial.clone())? {
- return Err(InvalidArgumentException {
- message: format!("Package is not installed: {}", initial),
- code: 0,
- }
+ return Err(InvalidArgumentException::new(format!(
+ "Package is not installed: {}",
+ initial
+ ))
.into());
}
@@ -91,10 +91,10 @@ impl InstallerInterface for NoopInstaller {
) -> anyhow::Result<Option<PhpMixed>> {
let mut repo = repo.borrow_mut();
if !repo.has_package(package.clone())? {
- return Err(InvalidArgumentException {
- message: format!("Package is not installed: {}", package),
- code: 0,
- }
+ return Err(InvalidArgumentException::new(format!(
+ "Package is not installed: {}",
+ package
+ ))
.into());
}
repo.remove_package(package);
diff --git a/crates/shirabe/src/installer/plugin_installer.rs b/crates/shirabe/src/installer/plugin_installer.rs
index 7683a7d5..abe313b7 100644
--- a/crates/shirabe/src/installer/plugin_installer.rs
+++ b/crates/shirabe/src/installer/plugin_installer.rs
@@ -121,13 +121,10 @@ impl InstallerInterface for PluginInstaller {
let extra = package.get_extra();
let class = extra.get("class").cloned().unwrap_or(PhpMixed::Null);
if empty(&class) {
- return Err(UnexpectedValueException {
- message: format!(
- "Error while installing {}, composer-plugin packages should have a class defined in their extra key to be usable.",
- package.get_pretty_name()
- ),
- code: 0,
- }.into());
+ return Err(UnexpectedValueException::new(format!(
+ "Error while installing {}, composer-plugin packages should have a class defined in their extra key to be usable.",
+ package.get_pretty_name()
+ )).into());
}
self.inner.download(package, prev_package).await
diff --git a/crates/shirabe/src/installer/project_installer.rs b/crates/shirabe/src/installer/project_installer.rs
index 59d44410..8b878352 100644
--- a/crates/shirabe/src/installer/project_installer.rs
+++ b/crates/shirabe/src/installer/project_installer.rs
@@ -52,10 +52,10 @@ impl InstallerInterface for ProjectInstaller {
if std::path::Path::new(install_path).exists()
&& !self.filesystem.borrow().is_dir_empty(install_path)
{
- return Err(InvalidArgumentException {
- message: format!("Project directory {} is not empty.", install_path),
- code: 0,
- }
+ return Err(InvalidArgumentException::new(format!(
+ "Project directory {} is not empty.",
+ install_path
+ ))
.into());
}
if !std::path::Path::new(install_path).is_dir() {
@@ -109,11 +109,7 @@ impl InstallerInterface for ProjectInstaller {
_initial: PackageInterfaceHandle,
_target: PackageInterfaceHandle,
) -> anyhow::Result<Option<PhpMixed>> {
- Err(InvalidArgumentException {
- message: "not supported".to_string(),
- code: 0,
- }
- .into())
+ Err(InvalidArgumentException::new("not supported".to_string()).into())
}
async fn uninstall(
@@ -121,11 +117,7 @@ impl InstallerInterface for ProjectInstaller {
_repo: &InstalledRepositoryInterfaceHandle,
_package: PackageInterfaceHandle,
) -> anyhow::Result<Option<PhpMixed>> {
- Err(InvalidArgumentException {
- message: "not supported".to_string(),
- code: 0,
- }
- .into())
+ Err(InvalidArgumentException::new("not supported".to_string()).into())
}
fn get_install_path(&self, _package: PackageInterfaceHandle) -> Option<String> {
diff --git a/crates/shirabe/src/io/base_io.rs b/crates/shirabe/src/io/base_io.rs
index 5dd7682f..52ef9a82 100644
--- a/crates/shirabe/src/io/base_io.rs
+++ b/crates/shirabe/src/io/base_io.rs
@@ -145,13 +145,11 @@ pub trait BaseIO: IOInterface {
}
if !Preg::is_match(php_regex!(r"{^[.A-Za-z0-9_]+$}"), &token_str) {
- return Err(anyhow::anyhow!(UnexpectedValueException {
- message: format!(
- "Your github oauth token for {} contains invalid characters: \"{}\"",
- domain, token_str
- ),
- code: 0,
- }));
+ return Err(UnexpectedValueException::new(format!(
+ "Your github oauth token for {} contains invalid characters: \"{}\"",
+ domain, token_str
+ ))
+ .into());
}
self.check_and_set_authentication(
domain,
diff --git a/crates/shirabe/src/io/buffer_io.rs b/crates/shirabe/src/io/buffer_io.rs
index bbe1db9f..d1224fdc 100644
--- a/crates/shirabe/src/io/buffer_io.rs
+++ b/crates/shirabe/src/io/buffer_io.rs
@@ -30,10 +30,9 @@ impl BufferIO {
let stream = match fopen("php://memory", "rw") {
Ok(stream) => stream,
Err(_) => {
- return Err(RuntimeException {
- message: "Unable to open memory output stream".to_string(),
- code: 0,
- }
+ return Err(RuntimeException::new(
+ "Unable to open memory output stream".to_string(),
+ )
.into());
}
};
@@ -116,10 +115,7 @@ impl BufferIO {
let mut input = self.inner.input.borrow_mut();
let Some(streamable) = input.as_streamable_mut() else {
- return Err(RuntimeException {
- message: "Setting the user inputs requires at least the version 3.2 of the symfony/console component.".to_string(),
- code: 0,
- }
+ return Err(RuntimeException::new("Setting the user inputs requires at least the version 3.2 of the symfony/console component.".to_string())
.into());
};
@@ -133,10 +129,9 @@ impl BufferIO {
let stream = match fopen("php://memory", "r+") {
Ok(stream) => stream,
Err(_) => {
- return Err(RuntimeException {
- message: "Unable to open memory output stream".to_string(),
- code: 0,
- }
+ return Err(RuntimeException::new(
+ "Unable to open memory output stream".to_string(),
+ )
.into());
}
};
diff --git a/crates/shirabe/src/io/console_io.rs b/crates/shirabe/src/io/console_io.rs
index 12b70318..443a3e51 100644
--- a/crates/shirabe/src/io/console_io.rs
+++ b/crates/shirabe/src/io/console_io.rs
@@ -348,7 +348,7 @@ impl ConsoleIO {
let mut input = self.input.borrow_mut();
question_helper
.ask(&mut *input, error_output, question)?
- .map_err(anyhow::Error::new)
+ .map_err(anyhow::Error::from)
}
}
@@ -490,18 +490,15 @@ impl IOInterfaceImmutable for ConsoleIO {
>,
> = Box::new(move |answer: Option<PhpMixed>| {
validator(answer.unwrap_or(PhpMixed::Null)).map_err(|e| {
- shirabe_external_packages::symfony::console::exception::InvalidArgumentException(
- shirabe_php_shim::InvalidArgumentException {
- message: e.to_string(),
- code: 0,
- },
+ shirabe_external_packages::symfony::console::exception::InvalidArgumentException::new(
+ e.to_string(),
)
})
});
question.set_validator(Some(adapted));
question
.set_max_attempts(attempts)
- .map_err(|e| anyhow::anyhow!(e.0.message))?;
+ .map_err(|e| anyhow::anyhow!(e.0.get_message().to_string()))?;
self.ask_question(&question)
}
diff --git a/crates/shirabe/src/json/json_file.rs b/crates/shirabe/src/json/json_file.rs
index 1d6a75ce..2d061ced 100644
--- a/crates/shirabe/src/json/json_file.rs
+++ b/crates/shirabe/src/json/json_file.rs
@@ -11,6 +11,7 @@ use crate::util::Silencer;
use indexmap::IndexMap;
use shirabe_external_packages::composer::pcre::{CaptureKey, Preg};
use shirabe_external_packages::seld::json_lint::{ParsingException, ParsingExceptionDetails};
+use shirabe_php_shim::Catch as _;
use shirabe_php_shim::{
InvalidArgumentException, JSON_PRETTY_PRINT, JSON_UNESCAPED_SLASHES, JSON_UNESCAPED_UNICODE,
PhpMixed, RuntimeException, UnexpectedValueException, dirname, file_exists, file_get_contents,
@@ -108,10 +109,9 @@ impl JsonFile {
io: Option<std::rc::Rc<std::cell::RefCell<dyn IOInterface>>>,
) -> anyhow::Result<Self> {
if http_downloader.is_none() && Preg::is_match(php_regex!(r"{^https?://}i"), &path) {
- return Err(InvalidArgumentException {
- message: "http urls require a HttpDownloader instance to be passed".to_string(),
- code: 0,
- }
+ return Err(InvalidArgumentException::new(
+ "http urls require a HttpDownloader instance to be passed".to_string(),
+ )
.into());
}
Ok(Self {
@@ -145,10 +145,10 @@ impl JsonFile {
.map(|s| s.to_string()))
} else {
if !Filesystem::is_readable(&self.path) {
- return Err(RuntimeException {
- message: format!("The file \"{}\" is not readable.", self.path),
- code: 0,
- }
+ return Err(RuntimeException::new(format!(
+ "The file \"{}\" is not readable.",
+ self.path
+ ))
.into());
}
if let Some(io) = &self.io
@@ -173,17 +173,13 @@ impl JsonFile {
Err(e) => {
// TransportException keeps its message verbatim; any other exception is wrapped
// with the "Could not read" prefix.
- if let Some(te) = e.downcast_ref::<TransportException>() {
- return Err(RuntimeException {
- message: te.message.clone(),
- code: 0,
- }
- .into());
- }
- return Err(RuntimeException {
- message: format!("Could not read {}\n\n{}", self.path, e),
- code: 0,
+ if let Some(te) = e.catch::<TransportException>() {
+ return Err(RuntimeException::new(te.get_message().to_string()).into());
}
+ return Err(RuntimeException::new(format!(
+ "Could not read {}\n\n{}",
+ self.path, e
+ ))
.into());
}
};
@@ -191,11 +187,7 @@ impl JsonFile {
let json = match json {
Some(j) => j,
None => {
- return Err(RuntimeException {
- message: format!("Could not read {}", self.path),
- code: 0,
- }
- .into());
+ return Err(RuntimeException::new(format!("Could not read {}", self.path)).into());
}
};
@@ -230,21 +222,18 @@ impl JsonFile {
let dir = dirname(&self.path);
if !is_dir(&dir) {
if file_exists(&dir) {
- return Err(UnexpectedValueException {
- message: format!(
- "{} exists and is not a directory.",
- realpath(&dir).unwrap_or_default(),
- ),
- code: 0,
- }
+ return Err(UnexpectedValueException::new(format!(
+ "{} exists and is not a directory.",
+ realpath(&dir).unwrap_or_default(),
+ ))
.into());
}
// PHP: @mkdir($dir, 0777, true)
if !Silencer::call(|| Ok(mkdir(&dir, 0o777, true))).unwrap_or(false) {
- return Err(UnexpectedValueException {
- message: format!("{} does not exist and could not be created.", dir),
- code: 0,
- }
+ return Err(UnexpectedValueException::new(format!(
+ "{} does not exist and could not be created.",
+ dir
+ ))
.into());
}
}
@@ -305,10 +294,10 @@ impl JsonFile {
/// @return true true on success
pub fn validate_schema(&self, schema: i64, schema_file: Option<&str>) -> anyhow::Result<bool> {
if !Filesystem::is_readable(&self.path) {
- return Err(RuntimeException {
- message: format!("The file \"{}\" is not readable.", self.path),
- code: 0,
- }
+ return Err(RuntimeException::new(format!(
+ "The file \"{}\" is not readable.",
+ self.path
+ ))
.into());
}
let content = file_get_contents(&self.path).unwrap_or_default();
@@ -446,10 +435,8 @@ impl JsonFile {
data: &T,
options: JsonEncodeOptions,
) -> anyhow::Result<String> {
- let json = json_encode_ex(data, options.to_flags()).map_err(|err| RuntimeException {
- message: format!("JSON encoding failed: {}", err),
- code: 0,
- })?;
+ let json = json_encode_ex(data, options.to_flags())
+ .map_err(|err| RuntimeException::new(format!("JSON encoding failed: {}", err)))?;
if options.pretty_print && options.indent != Self::INDENT_DEFAULT {
// Pretty printing and not using default indentation
diff --git a/crates/shirabe/src/json/json_manipulator.rs b/crates/shirabe/src/json/json_manipulator.rs
index eec823b6..d66fe645 100644
--- a/crates/shirabe/src/json/json_manipulator.rs
+++ b/crates/shirabe/src/json/json_manipulator.rs
@@ -36,10 +36,9 @@ impl JsonManipulator {
contents = "{}".to_string();
}
if !Preg::is_match3(php_regex!("#^\\{(.*)\\}$#s"), &contents, None) {
- return Err(InvalidArgumentException {
- message: "The json file must be an object ({})".to_string(),
- code: 0,
- }
+ return Err(InvalidArgumentException::new(
+ "The json file must be an object ({})".to_string(),
+ )
.into());
}
let newline = if strpos(&contents, "\r\n").is_some() {
@@ -823,10 +822,10 @@ impl JsonManipulator {
);
}
} else {
- return Err(LogicException {
- message: format!("Nothing matched above for: {}", children),
- code: 0,
- }
+ return Err(LogicException::new(format!(
+ "Nothing matched above for: {}",
+ children
+ ))
.into());
}
}
@@ -940,10 +939,7 @@ impl JsonManipulator {
children_clean = Some(children.clone());
}
- let children_clean = children_clean.ok_or_else(|| InvalidArgumentException {
- message: "JsonManipulator: $childrenClean is not defined. Please report at https://github.com/composer/composer/issues/new.".to_string(),
- code: 0,
- })?;
+ let children_clean = children_clean.ok_or_else(|| InvalidArgumentException::new("JsonManipulator: $childrenClean is not defined. Please report at https://github.com/composer/composer/issues/new.".to_string()))?;
// no child data left, $name was the only key in
let mut empty_match: IndexMap<String, String> = IndexMap::new();
@@ -1113,11 +1109,9 @@ impl JsonManipulator {
);
}
} else {
- return Err(LogicException {
- message: format!("Nothing matched above for: {}", children),
- code: 0,
- }
- .into());
+ return Err(
+ LogicException::new(format!("Nothing matched above for: {}", children)).into(),
+ );
}
self.contents = format!("{}{}{}", node_start, children, node_end);
@@ -1132,10 +1126,9 @@ impl JsonManipulator {
index: i64,
) -> anyhow::Result<bool> {
if index < 0 {
- return Err(InvalidArgumentException {
- message: "Index can only be positive integer".to_string(),
- code: 0,
- }
+ return Err(InvalidArgumentException::new(
+ "Index can only be positive integer".to_string(),
+ )
.into());
}
diff --git a/crates/shirabe/src/json/json_validation_exception.rs b/crates/shirabe/src/json/json_validation_exception.rs
index a63edda3..cb7370d2 100644
--- a/crates/shirabe/src/json/json_validation_exception.rs
+++ b/crates/shirabe/src/json/json_validation_exception.rs
@@ -11,7 +11,7 @@ pub struct JsonValidationException {
impl JsonValidationException {
pub fn new(message: String, errors: Vec<String>) -> Self {
Self {
- inner: Exception { message, code: 0 },
+ inner: Exception::new(message),
errors,
}
}
@@ -19,16 +19,10 @@ impl JsonValidationException {
pub fn get_errors(&self) -> &Vec<String> {
&self.errors
}
-
- pub fn get_message(&self) -> &str {
- &self.inner.message
- }
-}
-
-impl std::fmt::Display for JsonValidationException {
- fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
- write!(f, "{}", self.inner.message)
- }
}
-impl std::error::Error for JsonValidationException {}
+shirabe_php_shim::impl_php_exception!(
+ JsonValidationException,
+ inner,
+ r"Composer\Json\JsonValidationException"
+);
diff --git a/crates/shirabe/src/package/alias_package.rs b/crates/shirabe/src/package/alias_package.rs
index 088cd6ab..52b6efa4 100644
--- a/crates/shirabe/src/package/alias_package.rs
+++ b/crates/shirabe/src/package/alias_package.rs
@@ -435,10 +435,9 @@ impl PackageInterface for AliasPackage {
if let Some(existing) = self.repository.as_ref().and_then(|w| w.upgrade())
&& !std::rc::Rc::ptr_eq(&existing, repository.as_rc())
{
- return Err(LogicException {
- message: "A package can only be added to one repository".to_string(),
- code: 0,
- }
+ return Err(LogicException::new(
+ "A package can only be added to one repository".to_string(),
+ )
.into());
}
self.repository = Some(repository.downgrade());
diff --git a/crates/shirabe/src/package/archiver/archivable_files_finder.rs b/crates/shirabe/src/package/archiver/archivable_files_finder.rs
index ad2b41ab..f60c57f1 100644
--- a/crates/shirabe/src/package/archiver/archivable_files_finder.rs
+++ b/crates/shirabe/src/package/archiver/archivable_files_finder.rs
@@ -28,10 +28,10 @@ impl ArchivableFilesFinder {
let sources_real_path = realpath(sources);
if sources_real_path.is_none() {
- return Err(RuntimeException {
- message: format!("Could not realpath() the source directory \"{}\"", sources),
- code: 0,
- }
+ return Err(RuntimeException::new(format!(
+ "Could not realpath() the source directory \"{}\"",
+ sources
+ ))
.into());
}
let sources = fs.normalize_path(&sources_real_path.unwrap());
diff --git a/crates/shirabe/src/package/archiver/archive_manager.rs b/crates/shirabe/src/package/archiver/archive_manager.rs
index afc89f32..435843a6 100644
--- a/crates/shirabe/src/package/archiver/archive_manager.rs
+++ b/crates/shirabe/src/package/archiver/archive_manager.rs
@@ -114,10 +114,9 @@ impl ArchiveManager {
ignore_filters: bool,
) -> anyhow::Result<String> {
if format.is_empty() {
- return Err(anyhow::anyhow!(InvalidArgumentException {
- message: "Format must be specified".to_string(),
- code: 0,
- }));
+ return Err(
+ InvalidArgumentException::new("Format must be specified".to_string()).into(),
+ );
}
let mut usable_archiver_idx: Option<usize> = None;
@@ -131,10 +130,11 @@ impl ArchiveManager {
let usable_archiver_idx = match usable_archiver_idx {
Some(i) => i,
None => {
- return Err(anyhow::anyhow!(RuntimeException {
- message: format!("No archiver found to support {} format", format),
- code: 0,
- }));
+ return Err(RuntimeException::new(format!(
+ "No archiver found to support {} format",
+ format
+ ))
+ .into());
}
};
diff --git a/crates/shirabe/src/package/archiver/phar_archiver.rs b/crates/shirabe/src/package/archiver/phar_archiver.rs
index fbab8c67..0968f2a4 100644
--- a/crates/shirabe/src/package/archiver/phar_archiver.rs
+++ b/crates/shirabe/src/package/archiver/phar_archiver.rs
@@ -101,10 +101,10 @@ impl ArchiverInterface for PharArchiver {
} else if format == "tar.gz" || format == "tar.bz2" {
let compress_algo = *compress_formats.get(format.as_str()).unwrap();
if !PharData::can_compress(compress_algo) {
- return Err(RuntimeException {
- message: format!("Can not compress to {} format", format),
- code: 0,
- }
+ return Err(RuntimeException::new(format!(
+ "Can not compress to {} format",
+ format
+ ))
.into());
}
if format == "tar.gz" && function_exists("gzcompress") {
@@ -124,10 +124,10 @@ impl ArchiverInterface for PharArchiver {
if compress_formats.contains_key(format.as_str()) {
let compress_algo = *compress_formats.get(format.as_str()).unwrap();
if !PharData::can_compress(compress_algo) {
- return Err(RuntimeException {
- message: format!("Can not compress to {} format", format),
- code: 0,
- }
+ return Err(RuntimeException::new(format!(
+ "Can not compress to {} format",
+ format
+ ))
.into());
}
@@ -147,7 +147,7 @@ impl ArchiverInterface for PharArchiver {
"Could not create archive '{}' from '{}': {}",
target_outer, sources, e
);
- anyhow::anyhow!(RuntimeException { message, code: 0 })
+ RuntimeException::new(message).into()
})
}
diff --git a/crates/shirabe/src/package/archiver/zip_archiver.rs b/crates/shirabe/src/package/archiver/zip_archiver.rs
index 186d76c7..e5bb613d 100644
--- a/crates/shirabe/src/package/archiver/zip_archiver.rs
+++ b/crates/shirabe/src/package/archiver/zip_archiver.rs
@@ -111,7 +111,7 @@ impl ArchiverInterface for ZipArchiver {
sources,
zip.get_status_string()
);
- Err(RuntimeException { message, code: 0 }.into())
+ Err(RuntimeException::new(message).into())
}
fn supports(&self, format: String, _source_type: Option<String>) -> bool {
diff --git a/crates/shirabe/src/package/loader/array_loader.rs b/crates/shirabe/src/package/loader/array_loader.rs
index 0940183c..2c6d3971 100644
--- a/crates/shirabe/src/package/loader/array_loader.rs
+++ b/crates/shirabe/src/package/loader/array_loader.rs
@@ -69,23 +69,17 @@ impl ArrayLoader {
class: &str,
) -> anyhow::Result<CompleteOrRootPackage> {
if !config.contains_key("name") {
- return Err(UnexpectedValueException {
- message: format!(
- "Unknown package has no name defined ({}).",
- json_encode(&PhpMixed::Array(config.clone())).unwrap_or_default()
- ),
- code: 0,
- }
+ return Err(UnexpectedValueException::new(format!(
+ "Unknown package has no name defined ({}).",
+ json_encode(&PhpMixed::Array(config.clone())).unwrap_or_default()
+ ))
.into());
}
if !config.contains_key("version") || !is_scalar(config.get("version").unwrap()) {
- return Err(UnexpectedValueException {
- message: format!(
- "Package {} has no version defined.",
- config.get("name").and_then(|v| v.as_string()).unwrap_or("")
- ),
- code: 0,
- }
+ return Err(UnexpectedValueException::new(format!(
+ "Package {} has no version defined.",
+ config.get("name").and_then(|v| v.as_string()).unwrap_or("")
+ ))
.into());
}
let mut config_version = config.get("version").cloned().unwrap_or(PhpMixed::Null);
@@ -118,14 +112,11 @@ impl ArrayLoader {
{
Ok(v) => version = v,
Err(e) => {
- return Err(UnexpectedValueException {
- message: format!(
- "Failed to normalize version for package \"{}\": {}",
- config.get("name").and_then(|v| v.as_string()).unwrap_or(""),
- e
- ),
- code: 0,
- }
+ return Err(UnexpectedValueException::new(format!(
+ "Failed to normalize version for package \"{}\": {}",
+ config.get("name").and_then(|v| v.as_string()).unwrap_or(""),
+ e
+ ))
.into());
}
}
@@ -226,18 +217,14 @@ impl ArrayLoader {
})
.unwrap_or(false);
if !has_required {
- return Err(UnexpectedValueException {
- message: format!(
- "Package {}'s source key should be specified as {{\"type\": ..., \"url\": ..., \"reference\": ...}},\n{} given.",
-
- config
- .get("name")
- .and_then(|v| v.as_string())
- .unwrap_or(""),
- json_encode(&source).unwrap_or_default(),
- ),
- code: 0,
- }
+ return Err(UnexpectedValueException::new(format!(
+ "Package {}'s source key should be specified as {{\"type\": ..., \"url\": ..., \"reference\": ...}},\n{} given.",
+ config
+ .get("name")
+ .and_then(|v| v.as_string())
+ .unwrap_or(""),
+ json_encode(&source).unwrap_or_default(),
+ ))
.into());
}
let source_map = source_map.unwrap();
@@ -270,18 +257,14 @@ impl ArrayLoader {
.map(|m| m.contains_key("type") && m.contains_key("url"))
.unwrap_or(false);
if !has_required {
- return Err(UnexpectedValueException {
- message: format!(
- "Package {}'s dist key should be specified as {{\"type\": ..., \"url\": ..., \"reference\": ..., \"shasum\": ...}},\n{} given.",
-
- config
- .get("name")
- .and_then(|v| v.as_string())
- .unwrap_or(""),
- json_encode(&dist).unwrap_or_default(),
- ),
- code: 0,
- }
+ return Err(UnexpectedValueException::new(format!(
+ "Package {}'s dist key should be specified as {{\"type\": ..., \"url\": ..., \"reference\": ..., \"shasum\": ...}},\n{} given.",
+ config
+ .get("name")
+ .and_then(|v| v.as_string())
+ .unwrap_or(""),
+ json_encode(&dist).unwrap_or_default(),
+ ))
.into());
}
let dist_map = dist_map.unwrap();
@@ -672,13 +655,10 @@ impl ArrayLoader {
let parsed_constraint = match self.version_parser.parse_constraints(&constraint) {
Ok(c) => c,
Err(_e) => {
- return Err(UnexpectedValueException {
- message: format!(
- "Link constraint in {} {} > {} should be a valid version constraint, got \"{}\"",
- source, description, target, constraint
- ),
- code: 0,
- }
+ return Err(UnexpectedValueException::new(format!(
+ "Link constraint in {} {} > {} should be a valid version constraint, got \"{}\"",
+ source, description, target, constraint
+ ))
.into());
}
};
@@ -702,11 +682,9 @@ impl ArrayLoader {
config: &IndexMap<String, PhpMixed>,
) -> anyhow::Result<Option<String>> {
if !config.contains_key("version") || !is_scalar(config.get("version").unwrap()) {
- return Err(UnexpectedValueException {
- message: "no/invalid version defined".to_string(),
- code: 0,
- }
- .into());
+ return Err(
+ UnexpectedValueException::new("no/invalid version defined".to_string()).into(),
+ );
}
let mut config_version = config.get("version").cloned().unwrap_or(PhpMixed::Null);
if !is_string(&config_version) {
diff --git a/crates/shirabe/src/package/loader/invalid_package_exception.rs b/crates/shirabe/src/package/loader/invalid_package_exception.rs
index 2bd22c61..23251994 100644
--- a/crates/shirabe/src/package/loader/invalid_package_exception.rs
+++ b/crates/shirabe/src/package/loader/invalid_package_exception.rs
@@ -27,7 +27,7 @@ impl InvalidPackageException {
.join("\n")
);
Self {
- inner: Exception { message, code: 0 },
+ inner: Exception::new(message),
errors,
warnings,
data,
@@ -47,10 +47,8 @@ impl InvalidPackageException {
}
}
-impl std::fmt::Display for InvalidPackageException {
- fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
- write!(f, "{}", self.inner.message)
- }
-}
-
-impl std::error::Error for InvalidPackageException {}
+shirabe_php_shim::impl_php_exception!(
+ InvalidPackageException,
+ inner,
+ r"Composer\Package\Loader\InvalidPackageException"
+);
diff --git a/crates/shirabe/src/package/loader/json_loader.rs b/crates/shirabe/src/package/loader/json_loader.rs
index c30fbe07..d9e7100a 100644
--- a/crates/shirabe/src/package/loader/json_loader.rs
+++ b/crates/shirabe/src/package/loader/json_loader.rs
@@ -34,10 +34,7 @@ impl JsonLoader {
let config: IndexMap<String, PhpMixed> = match config {
PhpMixed::Array(m) => m,
_ => {
- return Err(TypeError {
- message: "Composer\\Package\\Loader\\LoaderInterface::load(): Argument #1 ($config) must be of type array".to_string(),
- code: 0,
- }
+ return Err(TypeError::new("Composer\\Package\\Loader\\LoaderInterface::load(): Argument #1 ($config) must be of type array".to_string())
.into());
}
};
diff --git a/crates/shirabe/src/package/loader/root_package_loader.rs b/crates/shirabe/src/package/loader/root_package_loader.rs
index 284bb175..e26a7e95 100644
--- a/crates/shirabe/src/package/loader/root_package_loader.rs
+++ b/crates/shirabe/src/package/loader/root_package_loader.rs
@@ -78,10 +78,7 @@ impl RootPackageLoader {
config["name"].as_string().unwrap_or(""),
false,
) {
- return Err(anyhow::anyhow!(RuntimeException {
- message: format!("Your package name {}", err),
- code: 0,
- }));
+ return Err(RuntimeException::new(format!("Your package name {}", err)).into());
}
let mut auto_versioned = false;
@@ -197,13 +194,10 @@ impl RootPackageLoader {
let package_name = config["name"].as_string().unwrap_or("").to_string();
if links.contains_key(&package_name) {
- return Err(anyhow::anyhow!(RuntimeException {
- message: format!(
- "Root package '{}' cannot require itself in its composer.json\nDid you accidentally name your root package after an external package?",
- package_name
- ),
- code: 0,
- }));
+ return Err(RuntimeException::new(format!(
+ "Root package '{}' cannot require itself in its composer.json\nDid you accidentally name your root package after an external package?",
+ package_name
+ )).into());
}
}
}
@@ -216,10 +210,7 @@ impl RootPackageLoader {
if let Some(err) =
ValidatingArrayLoader::has_package_naming_error(link_name, true)
{
- return Err(anyhow::anyhow!(RuntimeException {
- message: format!("{}.{}", link_type, err),
- code: 0,
- }));
+ return Err(RuntimeException::new(format!("{}.{}", link_type, err)).into());
}
}
}
@@ -291,14 +282,11 @@ impl RootPackageLoader {
return {
panic!(
"{}",
- UnexpectedValueException {
- message: format!(
+ UnexpectedValueException::new(format!(
"Invalid alias definition in \"{}\": \"{}\". Aliases should be in the form \"exact-version as other-exact-version\".",
req_name, req_version
- ),
- code: 0,
- }
- .message
+ ))
+ .get_message()
)
};
}
diff --git a/crates/shirabe/src/package/loader/validating_array_loader.rs b/crates/shirabe/src/package/loader/validating_array_loader.rs
index a050f2d7..fc8eed00 100644
--- a/crates/shirabe/src/package/loader/validating_array_loader.rs
+++ b/crates/shirabe/src/package/loader/validating_array_loader.rs
@@ -1583,11 +1583,12 @@ impl LoaderInterface for ValidatingArrayLoader {
}
if !self.errors.borrow().is_empty() {
- return Err(anyhow::anyhow!(InvalidPackageException::new(
+ return Err(InvalidPackageException::new(
self.errors.borrow().clone(),
self.warnings.borrow().clone(),
config.iter().map(|(k, v)| (k.clone(), v.clone())).collect(),
- )));
+ )
+ .into());
}
let package = self.loader.load(
diff --git a/crates/shirabe/src/package/locker.rs b/crates/shirabe/src/package/locker.rs
index a4d28861..3b20704a 100644
--- a/crates/shirabe/src/package/locker.rs
+++ b/crates/shirabe/src/package/locker.rs
@@ -26,6 +26,7 @@ use crate::util::ProcessExecutor;
use indexmap::IndexMap;
use shirabe_external_packages::composer::pcre::{CaptureKey, Preg};
use shirabe_external_packages::seld::json_lint::ParsingException;
+use shirabe_php_shim::Catch as _;
use shirabe_php_shim::{
DATE_RFC3339, LogicException, PhpMixed, RuntimeException, array_intersect, array_keys,
array_map, array_merge, file_get_contents, filemtime, function_exists, hash, in_array_loose,
@@ -194,10 +195,7 @@ impl Locker {
if let Some(packages_dev) = lock_data.get("packages-dev").cloned() {
locked_packages = array_merge(locked_packages, packages_dev);
} else {
- return Err(RuntimeException {
- message: "The lock file does not contain require-dev information, run install with the --no-dev option or delete it and run composer update to generate a new lock file.".to_string(),
- code: 0,
- }
+ return Err(RuntimeException::new("The lock file does not contain require-dev information, run install with the --no-dev option or delete it and run composer update to generate a new lock file.".to_string())
.into());
}
}
@@ -270,12 +268,10 @@ impl Locker {
return Ok(packages);
}
- Err(RuntimeException {
- message:
- "Your composer.lock is invalid. Run \"composer update\" to generate a new one."
- .to_string(),
- code: 0,
- }
+ Err(RuntimeException::new(
+ "Your composer.lock is invalid. Run \"composer update\" to generate a new one."
+ .to_string(),
+ )
.into())
}
@@ -438,10 +434,9 @@ impl Locker {
}
if !self.lock_file.exists() {
- return Err(LogicException {
- message: "No lockfile found. Unable to read locked packages".to_string(),
- code: 0,
- }
+ return Err(LogicException::new(
+ "No lockfile found. Unable to read locked packages".to_string(),
+ )
.into());
}
@@ -582,7 +577,7 @@ impl Locker {
let is_locked = match self.is_locked_result() {
Ok(b) => b,
Err(e) => {
- if e.downcast_ref::<ParsingException>().is_some() {
+ if e.is_instanceof::<ParsingException>() {
false
} else {
return Err(e);
@@ -641,13 +636,10 @@ impl Locker {
let contents = match contents {
Some(s) => s,
None => {
- return Err(RuntimeException {
- message: format!(
- "Unable to read {} contents to update the lock file hash.",
- composer_json.get_path()
- ),
- code: 0,
- }
+ return Err(RuntimeException::new(format!(
+ "Unable to read {} contents to update the lock file hash.",
+ composer_json.get_path()
+ ))
.into());
}
};
@@ -720,13 +712,10 @@ impl Locker {
let version = package.get_pretty_version();
if name.is_empty() || version.is_empty() {
- return Err(LogicException {
- message: format!(
- "Package \"{}\" has no version or name and can not be locked",
- package,
- ),
- code: 0,
- }
+ return Err(LogicException::new(format!(
+ "Package \"{}\" has no version or name and can not be locked",
+ package,
+ ))
.into());
}
diff --git a/crates/shirabe/src/package/package.rs b/crates/shirabe/src/package/package.rs
index bc99d08a..0f1e7d23 100644
--- a/crates/shirabe/src/package/package.rs
+++ b/crates/shirabe/src/package/package.rs
@@ -732,10 +732,9 @@ impl PackageInterface for Package {
if let Some(existing) = self.repository.as_ref().and_then(|w| w.upgrade())
&& !std::rc::Rc::ptr_eq(&existing, repository.as_rc())
{
- return Err(LogicException {
- message: "A package can only be added to one repository".to_string(),
- code: 0,
- }
+ return Err(LogicException::new(
+ "A package can only be added to one repository".to_string(),
+ )
.into());
}
self.repository = Some(repository.downgrade());
diff --git a/crates/shirabe/src/package/version/version_guesser.rs b/crates/shirabe/src/package/version/version_guesser.rs
index 98853952..1968ff11 100644
--- a/crates/shirabe/src/package/version/version_guesser.rs
+++ b/crates/shirabe/src/package/version/version_guesser.rs
@@ -750,10 +750,9 @@ impl VersionGuesser {
let version = match version {
Some(v) if !v.is_empty() => v,
_ => {
- return Err(RuntimeException {
- message: "COMPOSER_ROOT_VERSION not set or empty".to_string(),
- code: 0,
- }
+ return Err(RuntimeException::new(
+ "COMPOSER_ROOT_VERSION not set or empty".to_string(),
+ )
.into());
}
};
diff --git a/crates/shirabe/src/package/version/version_selector.rs b/crates/shirabe/src/package/version/version_selector.rs
index 84f2beef..733f342d 100644
--- a/crates/shirabe/src/package/version/version_selector.rs
+++ b/crates/shirabe/src/package/version/version_selector.rs
@@ -76,13 +76,10 @@ impl VersionSelector {
show_warnings: ShowWarnings,
) -> anyhow::Result<Option<crate::package::PackageInterfaceHandle>> {
if !base_package::STABILITIES.contains_key(preferred_stability) {
- return Err(shirabe_php_shim::UnexpectedValueException {
- message: format!(
- "Expected a valid stability name as 3rd argument, got {}",
- preferred_stability
- ),
- code: 0,
- }
+ return Err(shirabe_php_shim::UnexpectedValueException::new(format!(
+ "Expected a valid stability name as 3rd argument, got {}",
+ preferred_stability
+ ))
.into());
}
diff --git a/crates/shirabe/src/plugin/php_plugin_proxy.rs b/crates/shirabe/src/plugin/php_plugin_proxy.rs
index 686c05bd..af9d04db 100644
--- a/crates/shirabe/src/plugin/php_plugin_proxy.rs
+++ b/crates/shirabe/src/plugin/php_plugin_proxy.rs
@@ -2057,10 +2057,9 @@ impl PhpPluginProxy {
Ok(_) => Ok(()),
// TODO(plugin): the original exception class is collapsed to RuntimeException on
// this side of the boundary.
- Err(throw) => Err(anyhow::anyhow!(shirabe_php_shim::RuntimeException {
- message: throw.message,
- code: throw.code,
- })),
+ Err(throw) => {
+ Err(shirabe_php_shim::RuntimeException::with_code(throw.message, throw.code).into())
+ }
}
}
@@ -2080,10 +2079,9 @@ impl PhpPluginProxy {
)?;
match outcome {
Ok(value) => Ok(value.to_php_mixed()?),
- Err(throw) => Err(anyhow::anyhow!(shirabe_php_shim::RuntimeException {
- message: throw.message,
- code: throw.code,
- })),
+ Err(throw) => {
+ Err(shirabe_php_shim::RuntimeException::with_code(throw.message, throw.code).into())
+ }
}
}
}
@@ -2160,10 +2158,11 @@ impl EventSubscriberInterface for PhpPluginProxy {
// TODO(plugin): the original exception class is collapsed to RuntimeException on
// this side of the boundary.
Err(throw) => {
- return Err(anyhow::anyhow!(shirabe_php_shim::RuntimeException {
- message: throw.message,
- code: throw.code,
- }));
+ return Err(shirabe_php_shim::RuntimeException::with_code(
+ throw.message,
+ throw.code,
+ )
+ .into());
}
};
decode_subscribed_events(&self.class, value)
@@ -2191,10 +2190,11 @@ impl Capable for PhpPluginProxy {
// TODO(plugin): the original exception class is collapsed to RuntimeException on
// this side of the boundary.
Err(throw) => {
- return Err(anyhow::anyhow!(shirabe_php_shim::RuntimeException {
- message: throw.message,
- code: throw.code,
- }));
+ return Err(shirabe_php_shim::RuntimeException::with_code(
+ throw.message,
+ throw.code,
+ )
+ .into());
}
};
// PHP: `(array) $plugin->getCapabilities()` — the interface declares no return type,
@@ -2289,12 +2289,10 @@ fn decode_listener_priority(
}
fn subscribed_events_shape_error(class: &str, value: &PluginValue) -> anyhow::Error {
- anyhow::anyhow!(shirabe_php_shim::RuntimeException {
- message: format!(
- "{class}::getSubscribedEvents() returned an unsupported shape over RPC: {value:?}"
- ),
- code: 0,
- })
+ shirabe_php_shim::RuntimeException::new(format!(
+ "{class}::getSubscribedEvents() returned an unsupported shape over RPC: {value:?}"
+ ))
+ .into()
}
impl Drop for PhpPluginProxy {
@@ -2407,13 +2405,11 @@ impl PhpInstallerProxy {
}
fn unsupported_shape(&self, method: &str, value: &PluginValue) -> anyhow::Error {
- anyhow::anyhow!(shirabe_php_shim::RuntimeException {
- message: format!(
- "{}::{method}() returned an unsupported shape over RPC: {value:?}",
- self.handle.class
- ),
- code: 0,
- })
+ shirabe_php_shim::RuntimeException::new(format!(
+ "{}::{method}() returned an unsupported shape over RPC: {value:?}",
+ self.handle.class
+ ))
+ .into()
}
}
@@ -2632,15 +2628,11 @@ impl CommandProvider for PhpCommandProviderProxy {
PluginValue::List(items) => items,
PluginValue::Array(map) => map.into_values().collect(),
_ => {
- return Err(anyhow::anyhow!(
- shirabe_php_shim::UnexpectedValueException {
- message: format!(
- "Plugin capability {} failed to return an array from getCommands",
- self.handle.class
- ),
- code: 0,
- }
- ));
+ return Err(shirabe_php_shim::UnexpectedValueException::new(format!(
+ "Plugin capability {} failed to return an array from getCommands",
+ self.handle.class
+ ))
+ .into());
}
};
let mut commands: Vec<std::rc::Rc<std::cell::RefCell<dyn BaseCommand>>> = Vec::new();
@@ -2661,13 +2653,10 @@ impl CommandProvider for PhpCommandProviderProxy {
}
fn invalid_command_error(capability: &PhpObjHandle) -> anyhow::Error {
- anyhow::anyhow!(shirabe_php_shim::UnexpectedValueException {
- message: format!(
- "Plugin capability {} returned an invalid value, we expected an array of Composer\\Command\\BaseCommand objects",
- capability.class
- ),
- code: 0,
- })
+ shirabe_php_shim::UnexpectedValueException::new(format!(
+ "Plugin capability {} returned an invalid value, we expected an array of Composer\\Command\\BaseCommand objects",
+ capability.class
+ )).into()
}
impl Drop for PhpCommandProviderProxy {
@@ -2820,12 +2809,11 @@ impl PhpConsoleApplicationContext {
let app = match value {
PluginValue::PhpHandle(app) => app,
other => {
- return Err(anyhow::anyhow!(shirabe_php_shim::RuntimeException {
- message: format!(
+ return Err(shirabe_php_shim::RuntimeException::new(
+ format!(
"__shirabe_console_application_boot returned an unsupported shape over RPC: {other:?}"
- ),
- code: 0,
- }));
+ )
+ ).into());
}
};
*self.app.borrow_mut() = Some(app.clone());
@@ -3058,13 +3046,11 @@ impl PhpCommandProxy {
method: &str,
value: &PluginValue,
) -> anyhow::Error {
- anyhow::anyhow!(shirabe_php_shim::RuntimeException {
- message: format!(
- "{}::{method}() returned an unsupported shape over RPC: {value:?}",
- handle.class
- ),
- code: 0,
- })
+ shirabe_php_shim::RuntimeException::new(format!(
+ "{}::{method}() returned an unsupported shape over RPC: {value:?}",
+ handle.class
+ ))
+ .into()
}
}
@@ -3081,14 +3067,11 @@ impl Command for PhpCommandProxy {
) -> anyhow::Result<i64> {
let context = CONSOLE_APP_CONTEXT
.with(|slot| slot.borrow().clone())
- .ok_or_else(|| {
- anyhow::anyhow!(shirabe_php_shim::RuntimeException {
- message: format!(
+ .ok_or_else(|| -> anyhow::Error {
+ shirabe_php_shim::RuntimeException::new(format!(
"cannot run plugin-provided command {}: no worker-side console application context was published",
self.handle.class
- ),
- code: 0,
- })
+ )).into()
})?;
let app = context.booted_app()?;
let input_line = input.borrow().__to_string();
@@ -3110,13 +3093,12 @@ impl Command for PhpCommandProxy {
) -> anyhow::Result<i64> {
// `run` above never reaches this template hook; a direct call would bypass the
// worker-side binding, so it stays an explicit error.
- Err(anyhow::anyhow!(shirabe_php_shim::RuntimeException {
- message: format!(
+ Err(shirabe_php_shim::RuntimeException::new(
+ format!(
"plugin-provided command {} executes in the PHP worker through run(); execute() must not be called directly",
self.handle.class
- ),
- code: 0,
- }))
+ )
+ ).into())
}
fn is_proxy_command(&self) -> bool {
diff --git a/crates/shirabe/src/plugin/plugin_blocked_exception.rs b/crates/shirabe/src/plugin/plugin_blocked_exception.rs
index fcf52ace..b6a6070a 100644
--- a/crates/shirabe/src/plugin/plugin_blocked_exception.rs
+++ b/crates/shirabe/src/plugin/plugin_blocked_exception.rs
@@ -8,14 +8,12 @@ pub struct PluginBlockedException(pub UnexpectedValueException);
impl PluginBlockedException {
pub fn new(message: String) -> Self {
- Self(UnexpectedValueException { message, code: 0 })
+ Self(UnexpectedValueException::new(message))
}
}
-impl std::fmt::Display for PluginBlockedException {
- fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
- self.0.fmt(f)
- }
-}
-
-impl std::error::Error for PluginBlockedException {}
+shirabe_php_shim::impl_php_exception!(
+ PluginBlockedException,
+ 0,
+ r"Composer\Plugin\PluginBlockedException"
+);
diff --git a/crates/shirabe/src/plugin/plugin_manager.rs b/crates/shirabe/src/plugin/plugin_manager.rs
index 18239ce9..c68708a5 100644
--- a/crates/shirabe/src/plugin/plugin_manager.rs
+++ b/crates/shirabe/src/plugin/plugin_manager.rs
@@ -234,10 +234,7 @@ impl PluginManager {
let requires_composer = match requires_composer {
Some(r) => r,
None => {
- return Err(RuntimeException {
- message: format!("Plugin {} is missing a require statement for a version of the composer-plugin-api package.", package.get_name()),
- code: 0,
- }.into());
+ return Err(RuntimeException::new(format!("Plugin {} is missing a require statement for a version of the composer-plugin-api package.", package.get_name())).into());
}
};
@@ -316,10 +313,7 @@ impl PluginManager {
_ => false,
};
if class_is_empty {
- return Err(UnexpectedValueException {
- message: format!("Error while installing {}, composer-plugin packages should have a class defined in their extra key to be usable.", package.get_pretty_name()),
- code: 0,
- }.into());
+ return Err(UnexpectedValueException::new(format!("Error while installing {}, composer-plugin packages should have a class defined in their extra key to be usable.", package.get_pretty_name())).into());
}
// PHP: is_array($extra['class']) ? $extra['class'] : [$extra['class']] — an associative
// array iterates its values too, and a non-string entry reaches class_exists() where it
@@ -470,14 +464,11 @@ impl PluginManager {
if old_installer_plugin {
if !self.php_runtime_is_a(&class, "Composer\\Installer\\InstallerInterface")? {
- return Err(RuntimeException {
- message: format!(
- "Could not activate plugin \"{}\" as \"{}\" does not implement Composer\\Installer\\InstallerInterface",
- package.get_name(),
- class
- ),
- code: 0,
- }
+ return Err(RuntimeException::new(format!(
+ "Could not activate plugin \"{}\" as \"{}\" does not implement Composer\\Installer\\InstallerInterface",
+ package.get_name(),
+ class
+ ))
.into());
}
self.io.write_error(&format!(
@@ -511,14 +502,11 @@ impl PluginManager {
.push(PluginOrInstaller::Installer(installer));
} else if self.php_runtime_class_exists(&class, true)? {
if !self.php_runtime_is_a(&class, "Composer\\Plugin\\PluginInterface")? {
- return Err(RuntimeException {
- message: format!(
- "Could not activate plugin \"{}\" as \"{}\" does not implement Composer\\Plugin\\PluginInterface",
- package.get_name(),
- class
- ),
- code: 0,
- }
+ return Err(RuntimeException::new(format!(
+ "Could not activate plugin \"{}\" as \"{}\" does not implement Composer\\Plugin\\PluginInterface",
+ package.get_name(),
+ class
+ ))
.into());
}
let handle = self.php_runtime_new_object(&class)?;
@@ -534,14 +522,11 @@ impl PluginManager {
.or_default()
.push(PluginOrInstaller::Plugin(plugin));
} else if fail_on_missing_classes {
- return Err(UnexpectedValueException {
- message: format!(
- "Plugin {} could not be initialized, class not found: {}",
- package.get_name(),
- class
- ),
- code: 0,
- }
+ return Err(UnexpectedValueException::new(format!(
+ "Plugin {} could not be initialized, class not found: {}",
+ package.get_name(),
+ class
+ ))
.into());
}
}
@@ -1033,14 +1018,11 @@ impl PluginManager {
// || !trim(...)). Once the first branch has declined, a present key always fails one
// of the three disjuncts, so a present key unconditionally throws here.
if let Some(value) = capabilities.get(capability) {
- return Err(UnexpectedValueException {
- message: format!(
- "Plugin {} provided invalid capability class name(s), got {}",
- plugin.get_class_name(),
- var_export(value, true)
- ),
- code: 0,
- }
+ return Err(UnexpectedValueException::new(format!(
+ "Plugin {} provided invalid capability class name(s), got {}",
+ plugin.get_class_name(),
+ var_export(value, true)
+ ))
.into());
}
@@ -1066,14 +1048,11 @@ impl PluginManager {
Some(&mut PluginRpcDispatcher::default()),
))?;
if !matches!(exists, PluginValue::Bool(true)) {
- return Err(RuntimeException {
- message: format!(
- "Cannot instantiate Capability, as class {} from plugin {} does not exist.",
- capability_class,
- plugin.get_class_name()
- ),
- code: 0,
- }
+ return Err(RuntimeException::new(format!(
+ "Cannot instantiate Capability, as class {} from plugin {} does not exist.",
+ capability_class,
+ plugin.get_class_name()
+ ))
.into());
}
@@ -1116,12 +1095,9 @@ impl PluginManager {
if !php_is_a(&handle, "Composer\\Plugin\\Capability\\Capability")?
|| !php_is_a(&handle, capability_class_name)?
{
- return Err(RuntimeException {
- message: format!(
- "Class {capability_class} must implement both Composer\\Plugin\\Capability\\Capability and {capability_class_name}."
- ),
- code: 0,
- }
+ return Err(RuntimeException::new(format!(
+ "Class {capability_class} must implement both Composer\\Plugin\\Capability\\Capability and {capability_class_name}."
+ ))
.into());
}
diff --git a/crates/shirabe/src/question/strict_confirmation_question.rs b/crates/shirabe/src/question/strict_confirmation_question.rs
index 5141eb58..0fed4378 100644
--- a/crates/shirabe/src/question/strict_confirmation_question.rs
+++ b/crates/shirabe/src/question/strict_confirmation_question.rs
@@ -71,11 +71,8 @@ impl StrictConfirmationQuestion {
Box::new(|answer: Option<PhpMixed>| {
let answer = answer.unwrap_or(PhpMixed::Null);
if !is_bool(&answer) {
- return Err(InvalidArgumentException(
- shirabe_php_shim::InvalidArgumentException {
- message: "Please answer yes, y, no, or n.".to_string(),
- code: 0,
- },
+ return Err(InvalidArgumentException::new(
+ "Please answer yes, y, no, or n.".to_string(),
));
}
Ok(answer)
diff --git a/crates/shirabe/src/repository/artifact_repository.rs b/crates/shirabe/src/repository/artifact_repository.rs
index 99f340d1..2d16f137 100644
--- a/crates/shirabe/src/repository/artifact_repository.rs
+++ b/crates/shirabe/src/repository/artifact_repository.rs
@@ -47,10 +47,9 @@ impl ArtifactRepository {
io: std::rc::Rc<std::cell::RefCell<dyn IOInterface>>,
) -> anyhow::Result<Self> {
if !extension_loaded("zip") {
- return Err(RuntimeException {
- message: "The artifact repository requires PHP's zip extension".to_string(),
- code: 0,
- }
+ return Err(RuntimeException::new(
+ "The artifact repository requires PHP's zip extension".to_string(),
+ )
.into());
}
@@ -171,13 +170,10 @@ impl ArtifactRepository {
} else if file_extension == "zip" {
file_type = "zip";
} else {
- return Err(RuntimeException {
- message: format!(
- "Files with \"{}\" extensions aren't supported. Only ZIP and TAR/TAR.GZ/TGZ archives are supported.",
- file_extension
- ),
- code: 0,
- }
+ return Err(RuntimeException::new(format!(
+ "Files with \"{}\" extensions aren't supported. Only ZIP and TAR/TAR.GZ/TGZ archives are supported.",
+ file_extension
+ ))
.into());
}
@@ -228,10 +224,10 @@ impl ArtifactRepository {
.unwrap_or_default();
match self.loader.load(cfg, None) {
Ok(package) => Ok(Some(package)),
- Err(exception) => Err(UnexpectedValueException {
- message: format!("Failed loading package in {}: {}", pathname, exception),
- code: 0,
- }
+ Err(exception) => Err(UnexpectedValueException::new(format!(
+ "Failed loading package in {}: {}",
+ pathname, exception
+ ))
.into()),
}
}
diff --git a/crates/shirabe/src/repository/composer_repository.rs b/crates/shirabe/src/repository/composer_repository.rs
index b2476e1e..5371c2c3 100644
--- a/crates/shirabe/src/repository/composer_repository.rs
+++ b/crates/shirabe/src/repository/composer_repository.rs
@@ -38,6 +38,7 @@ use futures::stream::FuturesOrdered;
use indexmap::IndexMap;
use shirabe_external_packages::composer::pcre::{CaptureKey, Preg};
use shirabe_metadata_minifier::MetadataMinifier;
+use shirabe_php_shim::Catch as _;
use shirabe_php_shim::{
CmpOp, InvalidArgumentException, LogicException, PHP_EOL, PhpMixed, RuntimeException,
UnexpectedValueException, extension_loaded, hash, http_build_query, json_decode, parse_url_all,
@@ -183,10 +184,9 @@ impl ComposerRepository {
.to_string();
repo_config.insert("url".to_string(), PhpMixed::String(url_after.clone()));
if url_after.is_empty() {
- return Err(InvalidArgumentException {
- message: "The repository url must not be an empty string".to_string(),
- code: 0,
- }
+ return Err(InvalidArgumentException::new(
+ "The repository url must not be an empty string".to_string(),
+ )
.into());
}
@@ -214,10 +214,10 @@ impl ComposerRepository {
.and_then(|v| v.as_string())
.is_some_and(|s| !s.is_empty());
if url_bits_arr.is_none() || !scheme_present {
- return Err(UnexpectedValueException {
- message: format!("Invalid url given for Composer repository: {}", current_url),
- code: 0,
- }
+ return Err(UnexpectedValueException::new(format!(
+ "Invalid url given for Composer repository: {}",
+ current_url
+ ))
.into());
}
@@ -387,12 +387,10 @@ impl ComposerRepository {
if self.has_partial_packages()? {
if self.partial_packages_by_name.is_none() {
- return Err(LogicException {
- message:
- "hasPartialPackages failed to initialize $this->partialPackagesByName"
- .to_string(),
- code: 0,
- }
+ return Err(LogicException::new(
+ "hasPartialPackages failed to initialize $this->partialPackagesByName"
+ .to_string(),
+ )
.into());
}
@@ -403,17 +401,11 @@ impl ComposerRepository {
.create_packages(flat, Some("packages.json inline packages".to_string()));
}
- return Err(LogicException {
- message: "Composer repositories that have lazy providers and no available-packages list can not load the complete list of packages, use getPackageNames instead.".to_string(),
- code: 0,
- }.into());
+ return Err(LogicException::new("Composer repositories that have lazy providers and no available-packages list can not load the complete list of packages, use getPackageNames instead.".to_string()).into());
}
if has_providers {
- return Err(LogicException {
- message: "Composer repositories that have providers can not load the complete list of packages, use getPackageNames instead.".to_string(),
- code: 0,
- }.into());
+ return Err(LogicException::new("Composer repositories that have providers can not load the complete list of packages, use getPackageNames instead.".to_string()).into());
}
// PHP relies on ArrayRepository::getPackages() invoking the virtual initialize(),
@@ -516,10 +508,9 @@ impl ComposerRepository {
fn load_package_list(&mut self, package_filter: Option<&str>) -> anyhow::Result<Vec<String>> {
if self.list_url.is_none() {
- return Err(LogicException {
- message: "Make sure to call loadRootServerFile before loadPackageList".to_string(),
- code: 0,
- }
+ return Err(LogicException::new(
+ "Make sure to call loadRootServerFile before loadPackageList".to_string(),
+ )
.into());
}
@@ -636,10 +627,7 @@ impl ComposerRepository {
let constraint = package_name_map.get(&name).and_then(|c| c.clone());
for (_uid, candidate) in candidates.iter() {
if candidate.get_name() != name {
- return Err(LogicException {
- message: "whatProvides should never return a package with a different name than the requested one".to_string(),
- code: 0,
- }.into());
+ return Err(LogicException::new("whatProvides should never return a package with a different name than the requested one".to_string()).into());
}
names_found.insert(name.clone(), true);
@@ -946,16 +934,13 @@ impl ComposerRepository {
if !allow_partial_advisories && !is_full {
let data_mixed =
PhpMixed::Array(data.iter().map(|(k, v)| (k.clone(), v.clone())).collect());
- return Err(RuntimeException {
- message: format!(
- "Advisory for {} could not be loaded as a full advisory from {}{}{}",
- name,
- repo_name,
- PHP_EOL,
- var_export(&data_mixed, true),
- ),
- code: 0,
- }
+ return Err(RuntimeException::new(format!(
+ "Advisory for {} could not be loaded as a full advisory from {}{}{}",
+ name,
+ repo_name,
+ PHP_EOL,
+ var_export(&data_mixed, true),
+ ))
.into());
}
let affected_versions: &AnyConstraint = advisory.affected_versions();
@@ -1151,7 +1136,7 @@ impl ComposerRepository {
) {
Ok(resp) => resp.decode_json()?,
Err(e) => {
- if let Some(te) = e.downcast_ref::<TransportException>()
+ if let Some(te) = e.catch::<TransportException>()
&& te.get_status_code() == Some(404)
{
return Ok(result);
@@ -1183,11 +1168,10 @@ impl ComposerRepository {
if self.has_partial_packages()? {
if self.partial_packages_by_name.is_none() {
- return Err(LogicException {
- message: "hasPartialPackages failed to initialize $this->partialPackagesByName"
+ return Err(LogicException::new(
+ "hasPartialPackages failed to initialize $this->partialPackagesByName"
.to_string(),
- code: 0,
- }
+ )
.into());
}
for (_name, versions) in self.partial_packages_by_name.as_ref().unwrap().iter() {
@@ -1438,7 +1422,7 @@ impl ComposerRepository {
}
Err(e) => {
// 404s are acceptable for lazy provider repos
- if let Some(te) = e.downcast_ref::<TransportException>() {
+ if let Some(te) = e.catch::<TransportException>() {
let status_code = te.get_status_code();
if self.lazy_providers_url.is_some()
&& matches!(status_code, Some(404 | 499))
@@ -1726,12 +1710,10 @@ impl ComposerRepository {
let mut names_found: IndexMap<String, bool> = IndexMap::new();
if self.lazy_providers_url.is_none() {
- return Err(LogicException {
- message:
- "loadAsyncPackages only supports v2 protocol composer repos with a metadata-url"
- .to_string(),
- code: 0,
- }
+ return Err(LogicException::new(
+ "loadAsyncPackages only supports v2 protocol composer repos with a metadata-url"
+ .to_string(),
+ )
.into());
}
@@ -1964,10 +1946,7 @@ impl ComposerRepository {
package_name: Option<&str>,
) -> anyhow::Result<PhpMixed> {
if self.lazy_providers_url.is_none() {
- return Err(LogicException {
- message: "startCachedAsyncDownload only supports v2 protocol composer repos with a metadata-url".to_string(),
- code: 0,
- }.into());
+ return Err(LogicException::new("startCachedAsyncDownload only supports v2 protocol composer repos with a metadata-url".to_string()).into());
}
let name = strtolower(file_name);
@@ -2142,13 +2121,11 @@ impl ComposerRepository {
}
if !extension_loaded("openssl") && self.url.starts_with("https") {
- return Err(RuntimeException {
- message: format!(
- "You must enable the openssl extension in your php.ini to load information from {}",
- self.url
- ),
- code: 0,
- }.into());
+ return Err(RuntimeException::new(format!(
+ "You must enable the openssl extension in your php.ini to load information from {}",
+ self.url
+ ))
+ .into());
}
let mut data: Option<IndexMap<String, PhpMixed>> = None;
@@ -2387,13 +2364,10 @@ impl ComposerRepository {
api_url: api_url.clone(),
});
if api_url.is_none() && !self.has_available_package_list {
- return Err(UnexpectedValueException {
- message: format!(
- "Invalid security advisory configuration on {}: If the repository does not provide a security-advisories.api-url then available-packages or available-package-patterns are required to be provided for performance reason.",
- self.get_repo_name()
- ),
- code: 0,
- }.into());
+ return Err(UnexpectedValueException::new(format!(
+ "Invalid security advisory configuration on {}: If the repository does not provide a security-advisories.api-url then available-packages or available-package-patterns are required to be provided for performance reason.",
+ self.get_repo_name()
+ )).into());
}
}
}
@@ -2457,10 +2431,9 @@ impl ComposerRepository {
fn canonicalize_url(&self, url: &str) -> anyhow::Result<String> {
if url.is_empty() {
- return Err(InvalidArgumentException {
- message: "Expected a string with a value and not an empty string".to_string(),
- code: 0,
- }
+ return Err(InvalidArgumentException::new(
+ "Expected a string with a value and not an empty string".to_string(),
+ )
.into());
}
@@ -2491,11 +2464,9 @@ impl ComposerRepository {
let data = self.load_root_server_file(None)?;
let data = match data {
RootData::True => {
- return Err(LogicException {
- message: "loadRootServerFile should not return true during initialization"
- .to_string(),
- code: 0,
- }
+ return Err(LogicException::new(
+ "loadRootServerFile should not return true during initialization".to_string(),
+ )
.into());
}
RootData::Data(d) => d,
@@ -2724,19 +2695,16 @@ impl ComposerRepository {
})();
result.map_err(|e| {
- RuntimeException {
- message: format!(
- "Could not load packages in {}{}: [{}] {}",
- self.get_repo_name(),
- source
- .as_ref()
- .map(|s| format!(" from {}", s))
- .unwrap_or_default(),
- "Exception",
- e
- ),
- code: 0,
- }
+ RuntimeException::new(format!(
+ "Could not load packages in {}{}: [{}] {}",
+ self.get_repo_name(),
+ source
+ .as_ref()
+ .map(|s| format!(" from {}", s))
+ .unwrap_or_default(),
+ "Exception",
+ e
+ ))
.into()
})
}
@@ -2749,10 +2717,9 @@ impl ComposerRepository {
store_last_modified_time: bool,
) -> anyhow::Result<IndexMap<String, PhpMixed>> {
if filename.is_empty() {
- return Err(InvalidArgumentException {
- message: "$filename should not be an empty string".to_string(),
- code: 0,
- }
+ return Err(InvalidArgumentException::new(
+ "$filename should not be an empty string".to_string(),
+ )
.into());
}
@@ -2830,13 +2797,10 @@ impl ComposerRepository {
}
// TODO use scarier wording once we know for sure it doesn't do false positives anymore
- return Err(RepositorySecurityException(shirabe_php_shim::Exception {
- message: format!(
- "The contents of {} do not match its signature. This could indicate a man-in-the-middle attack or e.g. antivirus software corrupting files. Try running composer again and report this if you think it is a mistake.",
- filename
- ),
- code: 0,
- }).into());
+ return Err(RepositorySecurityException::new(format!(
+ "The contents of {} do not match its signature. This could indicate a man-in-the-middle attack or e.g. antivirus software corrupting files. Try running composer again and report this if you think it is a mistake.",
+ filename
+ )).into());
}
if let Some(dispatcher) = self.event_dispatcher.as_ref() {
@@ -2904,15 +2868,15 @@ impl ComposerRepository {
if e.downcast_ref::<RetryMarker>().is_some() {
continue;
}
- if e.downcast_ref::<LogicException>().is_some() {
+ if e.is_instanceof::<LogicException>() {
return Err(e);
}
- if let Some(te) = e.downcast_ref::<TransportException>()
+ if let Some(te) = e.catch::<TransportException>()
&& te.get_status_code() == Some(404)
{
return Err(e);
}
- if e.downcast_ref::<RepositorySecurityException>().is_some() {
+ if e.is_instanceof::<RepositorySecurityException>() {
return Err(e);
}
@@ -2948,10 +2912,7 @@ impl ComposerRepository {
match data {
Some(d) => Ok(d),
- None => Err(LogicException {
- message: "ComposerRepository: Undefined $data. Please report at https://github.com/composer/composer/issues/new.".to_string(),
- code: 0,
- }.into()),
+ None => Err(LogicException::new("ComposerRepository: Undefined $data. Please report at https://github.com/composer/composer/issues/new.".to_string()).into()),
}
}
@@ -2962,10 +2923,9 @@ impl ComposerRepository {
last_modified_time: &str,
) -> anyhow::Result<FetchFileIfLastModifiedResult> {
if filename.is_empty() {
- return Err(InvalidArgumentException {
- message: "$filename should not be an empty string".to_string(),
- code: 0,
- }
+ return Err(InvalidArgumentException::new(
+ "$filename should not be an empty string".to_string(),
+ )
.into());
}
@@ -3079,10 +3039,10 @@ impl ComposerRepository {
match result {
Ok(v) => Ok(v),
Err(e) => {
- if e.downcast_ref::<LogicException>().is_some() {
+ if e.is_instanceof::<LogicException>() {
return Err(e);
}
- if let Some(te) = e.downcast_ref::<TransportException>()
+ if let Some(te) = e.catch::<TransportException>()
&& te.get_status_code() == Some(404)
{
return Err(e);
@@ -3109,10 +3069,9 @@ impl ComposerRepository {
last_modified_time: Option<&str>,
) -> anyhow::Result<PhpMixed> {
if filename.is_empty() {
- return Err(InvalidArgumentException {
- message: "$filename should not be an empty string".to_string(),
- code: 0,
- }
+ return Err(InvalidArgumentException::new(
+ "$filename should not be an empty string".to_string(),
+ )
.into());
}
@@ -3263,7 +3222,7 @@ impl ComposerRepository {
cache_key: &str,
last_modified_time: Option<&str>,
) -> anyhow::Result<PhpMixed> {
- if let Some(te) = e.downcast_ref::<TransportException>()
+ if let Some(te) = e.catch::<TransportException>()
&& te.get_status_code() == Some(404)
{
self.packages_not_found_cache
@@ -3289,7 +3248,7 @@ impl ComposerRepository {
}
// special error code returned when network is being artificially disabled
- if let Some(te) = e.downcast_ref::<TransportException>()
+ if let Some(te) = e.catch::<TransportException>()
&& te.get_status_code() == Some(499)
{
let resp = Response::new(self.url.clone(), Some(404), Vec::new(), Some(String::new()));
@@ -3364,10 +3323,7 @@ impl ComposerRepository {
/// @return true if the package name is present in availablePackages or matched by availablePackagePatterns
pub(crate) fn lazy_providers_repo_contains(&self, name: &str) -> anyhow::Result<bool> {
if !self.has_available_package_list {
- return Err(LogicException {
- message: "lazyProvidersRepoContains should not be called unless hasAvailablePackageList is true".to_string(),
- code: 0,
- }.into());
+ return Err(LogicException::new("lazyProvidersRepoContains should not be called unless hasAvailablePackageList is true".to_string()).into());
}
if let Some(ref available) = self.available_packages
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(),
diff --git a/crates/shirabe/src/repository/filter_repository.rs b/crates/shirabe/src/repository/filter_repository.rs
index d7be0a9f..98cef1d0 100644
--- a/crates/shirabe/src/repository/filter_repository.rs
+++ b/crates/shirabe/src/repository/filter_repository.rs
@@ -49,13 +49,10 @@ impl FilterRepository {
));
}
_ => {
- return Err(InvalidArgumentException {
- message: format!(
- r#""only" key for repository {} should be an array"#,
- repo.get_repo_name()?
- ),
- code: 0,
- }
+ return Err(InvalidArgumentException::new(format!(
+ r#""only" key for repository {} should be an array"#,
+ repo.get_repo_name()?
+ ))
.into());
}
}
@@ -79,25 +76,19 @@ impl FilterRepository {
));
}
_ => {
- return Err(InvalidArgumentException {
- message: format!(
- r#""exclude" key for repository {} should be an array"#,
- repo.get_repo_name()?
- ),
- code: 0,
- }
+ return Err(InvalidArgumentException::new(format!(
+ r#""exclude" key for repository {} should be an array"#,
+ repo.get_repo_name()?
+ ))
.into());
}
}
}
if exclude.is_some() && only.is_some() {
- return Err(InvalidArgumentException {
- message: format!(
- r#"Only one of "only" and "exclude" can be specified for repository {}"#,
- repo.get_repo_name()?
- ),
- code: 0,
- }
+ return Err(InvalidArgumentException::new(format!(
+ r#"Only one of "only" and "exclude" can be specified for repository {}"#,
+ repo.get_repo_name()?
+ ))
.into());
}
if let Some(canonical_val) = options.get("canonical") {
@@ -106,13 +97,10 @@ impl FilterRepository {
canonical = *b;
}
_ => {
- return Err(InvalidArgumentException {
- message: format!(
- r#""canonical" key for repository {} should be a boolean"#,
- repo.get_repo_name()?
- ),
- code: 0,
- }
+ return Err(InvalidArgumentException::new(format!(
+ r#""canonical" key for repository {} should be a boolean"#,
+ repo.get_repo_name()?
+ ))
.into());
}
}
diff --git a/crates/shirabe/src/repository/invalid_repository_exception.rs b/crates/shirabe/src/repository/invalid_repository_exception.rs
index e7aa8509..ed84759c 100644
--- a/crates/shirabe/src/repository/invalid_repository_exception.rs
+++ b/crates/shirabe/src/repository/invalid_repository_exception.rs
@@ -8,14 +8,12 @@ pub struct InvalidRepositoryException(pub Exception);
impl InvalidRepositoryException {
pub fn new(message: String) -> Self {
- Self(Exception { message, code: 0 })
+ Self(Exception::new(message))
}
}
-impl std::fmt::Display for InvalidRepositoryException {
- fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
- self.0.fmt(f)
- }
-}
-
-impl std::error::Error for InvalidRepositoryException {}
+shirabe_php_shim::impl_php_exception!(
+ InvalidRepositoryException,
+ 0,
+ r"Composer\Repository\InvalidRepositoryException"
+);
diff --git a/crates/shirabe/src/repository/package_repository.rs b/crates/shirabe/src/repository/package_repository.rs
index 62c8c5b3..810b0e13 100644
--- a/crates/shirabe/src/repository/package_repository.rs
+++ b/crates/shirabe/src/repository/package_repository.rs
@@ -16,7 +16,7 @@ use crate::repository::{
};
use indexmap::IndexMap;
use shirabe_external_packages::composer::pcre::Preg;
-use shirabe_php_shim::{Exception, PhpMixed, RuntimeException, php_regex, var_export};
+use shirabe_php_shim::{PhpMixed, RuntimeException, php_regex, var_export};
use shirabe_semver::constraint::AnyConstraint;
#[derive(Debug)]
@@ -72,10 +72,7 @@ impl PackageRepository {
e,
shirabe_php_shim::json_encode(package).unwrap_or_default()
);
- return Ok(Err(InvalidRepositoryException(Exception {
- message: msg,
- code: 0,
- })));
+ return Ok(Err(InvalidRepositoryException::new(msg)));
}
};
self.inner.add_package(package_loaded)?;
@@ -101,7 +98,7 @@ impl PackageRepository {
// skips re-initializing it.
fn ensure_initialized(&self) -> anyhow::Result<()> {
if !self.inner.is_initialized() {
- self.initialize()?.map_err(anyhow::Error::new)?;
+ self.initialize()?.map_err(anyhow::Error::from)?;
}
Ok(())
}
@@ -234,15 +231,13 @@ impl AdvisoryProviderInterface for PackageRepository {
};
if !allow_partial_advisories && matches!(advisory, AnySecurityAdvisory::Partial(_))
{
- return Err(anyhow::anyhow!(RuntimeException {
- message: format!(
- "Advisory for {} could not be loaded as a full advisory from {}\n{}",
- package_name,
- self.get_repo_name()?,
- var_export(data, true)
- ),
- code: 0,
- }));
+ return Err(RuntimeException::new(format!(
+ "Advisory for {} could not be loaded as a full advisory from {}\n{}",
+ package_name,
+ self.get_repo_name()?,
+ var_export(data, true)
+ ))
+ .into());
}
if !advisory.affected_versions().matches(package_constraint) {
diff --git a/crates/shirabe/src/repository/path_repository.rs b/crates/shirabe/src/repository/path_repository.rs
index ec2da043..313fc75e 100644
--- a/crates/shirabe/src/repository/path_repository.rs
+++ b/crates/shirabe/src/repository/path_repository.rs
@@ -56,11 +56,9 @@ impl PathRepository {
process: Option<std::rc::Rc<std::cell::RefCell<ProcessExecutor>>>,
) -> anyhow::Result<Self> {
if !repo_config.contains_key("url") {
- return Err(RuntimeException {
- message: "You must specify the `url` configuration for the path repository"
- .to_string(),
- code: 0,
- }
+ return Err(RuntimeException::new(
+ "You must specify the `url` configuration for the path repository".to_string(),
+ )
.into());
}
@@ -172,13 +170,10 @@ impl PathRepository {
}
}
- return Err(RuntimeException {
- message: format!(
- "The `url` supplied for the path ({}) repository does not exist",
- self.url
- ),
- code: 0,
- }
+ return Err(RuntimeException::new(format!(
+ "The `url` supplied for the path ({}) repository does not exist",
+ self.url
+ ))
.into());
}
@@ -355,10 +350,10 @@ impl PathRepository {
self.inner
.add_package(self.loader.load(package.clone(), None).map_err(|e| {
- RuntimeException {
- message: format!("Failed loading the package in {}", composer_file_path),
- code: 0,
- }
+ RuntimeException::new(format!(
+ "Failed loading the package in {}",
+ composer_file_path
+ ))
})?);
}
@@ -371,13 +366,10 @@ impl PathRepository {
if defined("GLOB_BRACE") {
flags |= GLOB_BRACE;
} else if self.url.contains('{') || self.url.contains('}') {
- return Err(RuntimeException {
- message: format!(
- "The operating system does not support GLOB_BRACE which is required for the url {}",
- self.url
- ),
- code: 0,
- }
+ return Err(RuntimeException::new(format!(
+ "The operating system does not support GLOB_BRACE which is required for the url {}",
+ self.url
+ ))
.into());
}
diff --git a/crates/shirabe/src/repository/platform_repository.rs b/crates/shirabe/src/repository/platform_repository.rs
index 944bb4db..0b32e157 100644
--- a/crates/shirabe/src/repository/platform_repository.rs
+++ b/crates/shirabe/src/repository/platform_repository.rs
@@ -65,24 +65,20 @@ impl PlatformRepository {
let mut overrides_map: IndexMap<String, PlatformOverride> = IndexMap::new();
for (name, version) in overrides {
if !is_string(&version) && !matches!(version, PhpMixed::Bool(false)) {
- return Err(anyhow::anyhow!(UnexpectedValueException {
- message: format!(
- "config.platform.{} should be a string or false, but got {} {}",
- name,
- shirabe_php_shim::get_debug_type(&version),
- var_export(&version, true)
- ),
- code: 0,
- }));
+ return Err(UnexpectedValueException::new(format!(
+ "config.platform.{} should be a string or false, but got {} {}",
+ name,
+ shirabe_php_shim::get_debug_type(&version),
+ var_export(&version, true)
+ ))
+ .into());
}
if name == "php" && matches!(version, PhpMixed::Bool(false)) {
- return Err(anyhow::anyhow!(UnexpectedValueException {
- message: format!(
- "config.platform.{} cannot be set to false as you cannot disable php entirely.",
- name
- ),
- code: 0,
- }));
+ return Err(UnexpectedValueException::new(format!(
+ "config.platform.{} cannot be set to false as you cannot disable php entirely.",
+ name
+ ))
+ .into());
}
overrides_map.insert(
strtolower(&name),
@@ -153,13 +149,11 @@ impl PlatformRepository {
for r#override in &overrides {
// Check that it's a platform package.
if !Self::is_platform_package(&r#override.name) {
- return Err(anyhow::anyhow!(InvalidArgumentException {
- message: format!(
- "Invalid platform package name in config.platform: {}",
- r#override.name
- ),
- code: 0,
- }));
+ return Err(InvalidArgumentException::new(format!(
+ "Invalid platform package name in config.platform: {}",
+ r#override.name
+ ))
+ .into());
}
if !matches!(r#override.version, PhpMixed::Bool(false)) {
@@ -1488,13 +1482,11 @@ impl PlatformRepository {
pub fn add_package(&mut self, package: PackageInterfaceHandle) -> anyhow::Result<()> {
if package.as_complete().is_none() {
- return Err(anyhow::anyhow!(UnexpectedValueException {
- message: format!(
- "Expected CompletePackage but got {}",
- get_class(&PhpMixed::Null)
- ),
- code: 0,
- }));
+ return Err(UnexpectedValueException::new(format!(
+ "Expected CompletePackage but got {}",
+ get_class(&PhpMixed::Null)
+ ))
+ .into());
}
let name = package.get_name();
diff --git a/crates/shirabe/src/repository/repository_factory.rs b/crates/shirabe/src/repository/repository_factory.rs
index 856f58ad..a15d3a97 100644
--- a/crates/shirabe/src/repository/repository_factory.rs
+++ b/crates/shirabe/src/repository/repository_factory.rs
@@ -73,10 +73,7 @@ impl RepositoryFactory {
repo_config.insert("json".to_string(), PhpMixed::String(repository.to_string()));
return Ok(repo_config);
} else {
- return Err(InvalidArgumentException {
- message: format!("Invalid repository URL ({}) given. This file does not contain a valid composer repository.", repository),
- code: 0,
- }.into());
+ return Err(InvalidArgumentException::new(format!("Invalid repository URL ({}) given. This file does not contain a valid composer repository.", repository)).into());
}
}
@@ -87,10 +84,7 @@ impl RepositoryFactory {
return Ok(repo_config);
}
- Err(InvalidArgumentException {
- message: format!("Invalid repository url ({}) given. Has to be a .json file, an http url or a JSON object.", repository),
- code: 0,
- }.into())
+ Err(InvalidArgumentException::new(format!("Invalid repository url ({}) given. Has to be a .json file, an http url or a JSON object.", repository)).into())
}
pub fn from_string(
@@ -121,13 +115,9 @@ impl RepositoryFactory {
let repos =
Self::create_repos(rm, vec![PhpMixed::Array(repo_config.into_iter().collect())])?;
// PHP: return current($repos);
- let (_, first) = repos
- .into_iter()
- .next()
- .ok_or_else(|| UnexpectedValueException {
- message: "create_repos returned no repository".to_string(),
- code: 0,
- })?;
+ let (_, first) = repos.into_iter().next().ok_or_else(|| {
+ UnexpectedValueException::new("create_repos returned no repository".to_string())
+ })?;
Ok(first)
}
@@ -149,10 +139,11 @@ impl RepositoryFactory {
let rm = if let Some(rm) = rm {
rm
} else {
- let io = io.ok_or_else(|| InvalidArgumentException {
- message: "This function requires either an IOInterface or a RepositoryManager"
- .to_string(),
- code: 0,
+ let io = io.ok_or_else(|| {
+ InvalidArgumentException::new(
+ "This function requires either an IOInterface or a RepositoryManager"
+ .to_string(),
+ )
})?;
owned_rm = Self::manager(
io.clone(),
@@ -243,21 +234,15 @@ impl RepositoryFactory {
for (index, repo) in repo_configs.into_iter().enumerate() {
match &repo {
PhpMixed::String(_) => {
- return Err(UnexpectedValueException {
- message: "\"repositories\" should be an array of repository definitions, only a single repository was given".to_string(),
- code: 0,
- }.into());
+ return Err(UnexpectedValueException::new("\"repositories\" should be an array of repository definitions, only a single repository was given".to_string()).into());
}
PhpMixed::Array(repo_arr) => {
if !repo_arr.contains_key("type") {
- return Err(UnexpectedValueException {
- message: format!(
- "Repository \"{}\" ({}) must have a type defined",
- index,
- json_encode(&repo).unwrap_or_default()
- ),
- code: 0,
- }
+ return Err(UnexpectedValueException::new(format!(
+ "Repository \"{}\" ({}) must have a type defined",
+ index,
+ json_encode(&repo).unwrap_or_default()
+ ))
.into());
}
let repo_type = repo_arr
@@ -296,15 +281,12 @@ impl RepositoryFactory {
}
}
_ => {
- return Err(UnexpectedValueException {
- message: format!(
- "Repository \"{}\" ({}) should be an array, {} given",
- index,
- json_encode(&repo).unwrap_or_default(),
- get_debug_type(&repo)
- ),
- code: 0,
- }
+ return Err(UnexpectedValueException::new(format!(
+ "Repository \"{}\" ({}) should be an array, {} given",
+ index,
+ json_encode(&repo).unwrap_or_default(),
+ get_debug_type(&repo)
+ ))
.into());
}
}
diff --git a/crates/shirabe/src/repository/repository_manager.rs b/crates/shirabe/src/repository/repository_manager.rs
index 7fd2f80a..10ac973d 100644
--- a/crates/shirabe/src/repository/repository_manager.rs
+++ b/crates/shirabe/src/repository/repository_manager.rs
@@ -100,10 +100,10 @@ impl RepositoryManager {
name: Option<&str>,
) -> anyhow::Result<RepositoryInterfaceHandle> {
if !self.repository_classes.contains_key(r#type) {
- return Err(InvalidArgumentException {
- message: format!("Repository type is not registered: {}", r#type),
- code: 0,
- }
+ return Err(InvalidArgumentException::new(format!(
+ "Repository type is not registered: {}",
+ r#type
+ ))
.into());
}
@@ -193,10 +193,10 @@ impl RepositoryManager {
)),
// TODO(plugin): `setRepositoryClass` lets a plugin register a repository class of
// its own, which needs a Rust-side counterpart before it can be built here.
- other => Err(anyhow::anyhow!(RuntimeException {
- message: format!("Repository class has no Rust implementation: {other}"),
- code: 0,
- })),
+ other => Err(RuntimeException::new(format!(
+ "Repository class has no Rust implementation: {other}"
+ ))
+ .into()),
}
}
diff --git a/crates/shirabe/src/repository/repository_security_exception.rs b/crates/shirabe/src/repository/repository_security_exception.rs
index b517cad9..13f2fe72 100644
--- a/crates/shirabe/src/repository/repository_security_exception.rs
+++ b/crates/shirabe/src/repository/repository_security_exception.rs
@@ -6,10 +6,14 @@ use shirabe_php_shim::Exception;
#[derive(Debug)]
pub struct RepositorySecurityException(pub Exception);
-impl std::fmt::Display for RepositorySecurityException {
- fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
- self.0.fmt(f)
+impl RepositorySecurityException {
+ pub fn new(message: String) -> Self {
+ Self(Exception::new(message))
}
}
-impl std::error::Error for RepositorySecurityException {}
+shirabe_php_shim::impl_php_exception!(
+ RepositorySecurityException,
+ 0,
+ r"Composer\Repository\RepositorySecurityException"
+);
diff --git a/crates/shirabe/src/repository/repository_set.rs b/crates/shirabe/src/repository/repository_set.rs
index def73f14..bd57ec20 100644
--- a/crates/shirabe/src/repository/repository_set.rs
+++ b/crates/shirabe/src/repository/repository_set.rs
@@ -21,6 +21,7 @@ use crate::repository::LockArrayRepositoryHandle;
use crate::repository::PlatformRepository;
use crate::repository::{FindPackageConstraint, RepositoryInterfaceHandle};
use indexmap::IndexMap;
+use shirabe_php_shim::Catch as _;
use shirabe_php_shim::{LogicException, RuntimeException, ksort, strtolower};
use shirabe_semver::constraint::AnyConstraint;
use shirabe_semver::constraint::MatchAllConstraint;
@@ -155,10 +156,7 @@ impl RepositorySet {
/// @param RepositoryInterface $repo A package repository
pub fn add_repository(&mut self, repo: RepositoryInterfaceHandle) -> anyhow::Result<()> {
if self.locked {
- return Err(RuntimeException {
- message: "Pool has already been created from this repository set, it cannot be modified anymore.".to_string(),
- code: 0,
- }
+ return Err(RuntimeException::new("Pool has already been created from this repository set, it cannot be modified anymore.".to_string())
.into());
}
@@ -374,17 +372,17 @@ impl RepositorySet {
Err(e) => {
// PHP catches only \Composer\Downloader\TransportException; other
// exceptions propagate uncaught.
- if e.downcast_ref::<TransportException>().is_none() {
+ if !e.is_instanceof::<TransportException>() {
return Err(e);
}
if !ignore_unreachable {
return Err(e);
}
let message = e
- .downcast_ref::<TransportException>()
+ .catch::<TransportException>()
.unwrap()
- .message
- .clone();
+ .get_message()
+ .to_string();
unreachable_repos.push(message);
}
}
@@ -482,11 +480,9 @@ impl RepositorySet {
|| repo_ref.as_any().is::<InstalledRepository>()
};
if is_installed && !self.allow_installed_repositories {
- return Err(LogicException {
- message: "The pool can not accept packages from an installed repository"
- .to_string(),
- code: 0,
- }
+ return Err(LogicException::new(
+ "The pool can not accept packages from an installed repository".to_string(),
+ )
.into());
}
}
@@ -505,11 +501,9 @@ impl RepositorySet {
|| repo_ref.as_any().is::<InstalledRepository>()
};
if is_installed && !self.allow_installed_repositories {
- return Err(LogicException {
- message: "The pool can not accept packages from an installed repository"
- .to_string(),
- code: 0,
- }
+ return Err(LogicException::new(
+ "The pool can not accept packages from an installed repository".to_string(),
+ )
.into());
}
}
@@ -582,10 +576,7 @@ impl RepositorySet {
let mut allowed_packages: Vec<String> = vec![];
for package_name in &package_names {
if PlatformRepository::is_platform_package(package_name) {
- return Err(LogicException {
- message: "createPoolForPackage(s) can not be used for platform packages, as they are never loaded by the PoolBuilder which expects them to be fixed. Use createPoolWithAllPackages or pass in a proper request with the platform packages you need fixed in it.".to_string(),
- code: 0,
- }
+ return Err(LogicException::new("createPoolForPackage(s) can not be used for platform packages, as they are never loaded by the PoolBuilder which expects them to be fixed. Use createPoolWithAllPackages or pass in a proper request with the platform packages you need fixed in it.".to_string())
.into());
}
diff --git a/crates/shirabe/src/repository/vcs/forgejo_driver.rs b/crates/shirabe/src/repository/vcs/forgejo_driver.rs
index 0719701f..e4ebe379 100644
--- a/crates/shirabe/src/repository/vcs/forgejo_driver.rs
+++ b/crates/shirabe/src/repository/vcs/forgejo_driver.rs
@@ -16,6 +16,7 @@ use crate::util::ForgejoUrl;
use crate::util::http::Response;
use indexmap::IndexMap;
use shirabe_external_packages::composer::pcre::{CaptureKey, Preg};
+use shirabe_php_shim::Catch as _;
use shirabe_php_shim::{
PhpMixed, RuntimeException, base64_decode, explode, extension_loaded, php_regex, urlencode,
};
@@ -107,7 +108,7 @@ impl ForgejoDriver {
);
let response = self
.get_contents(&resource_url, false)
- .map_err(|e| anyhow::anyhow!("{}", e.message))?;
+ .map_err(|e| anyhow::anyhow!("{}", e.get_message()))?;
let mut resource = response.decode_json()?;
// The Forgejo contents API only returns files up to 1MB as base64 encoded files;
@@ -134,7 +135,7 @@ impl ForgejoDriver {
if let Some(git_url) = git_url {
resource = self
.get_contents(&git_url, false)
- .map_err(|e| anyhow::anyhow!("{}", e.message))?
+ .map_err(|e| anyhow::anyhow!("{}", e.get_message()))?
.decode_json()?;
}
}
@@ -157,22 +158,22 @@ impl ForgejoDriver {
Some(b64) => match base64_decode(&b64) {
Some(bytes) => match String::from_utf8(bytes) {
Ok(s) => Ok(Some(s)),
- Err(_) => Err(RuntimeException {
- message: format!("Could not retrieve {} for {}", file, identifier),
- code: 0,
- }
+ Err(_) => Err(RuntimeException::new(format!(
+ "Could not retrieve {} for {}",
+ file, identifier
+ ))
.into()),
},
- None => Err(RuntimeException {
- message: format!("Could not retrieve {} for {}", file, identifier),
- code: 0,
- }
+ None => Err(RuntimeException::new(format!(
+ "Could not retrieve {} for {}",
+ file, identifier
+ ))
.into()),
},
- None => Err(RuntimeException {
- message: format!("Could not retrieve {} for {}", file, identifier),
- code: 0,
- }
+ None => Err(RuntimeException::new(format!(
+ "Could not retrieve {} for {}",
+ file, identifier
+ ))
.into()),
}
}
@@ -193,7 +194,7 @@ impl ForgejoDriver {
);
let commit = self
.get_contents(&resource_url, false)
- .map_err(|e| anyhow::anyhow!("{}", e.message))?
+ .map_err(|e| anyhow::anyhow!("{}", e.get_message()))?
.decode_json()?;
let date_str = if let PhpMixed::Array(ref arr) = commit {
@@ -208,9 +209,8 @@ impl ForgejoDriver {
None
};
- let date_str = date_str.ok_or_else(|| RuntimeException {
- message: format!("Could not parse commit date for {}", identifier),
- code: 0,
+ let date_str = date_str.ok_or_else(|| {
+ RuntimeException::new(format!("Could not parse commit date for {}", identifier))
})?;
let date: chrono::DateTime<chrono::FixedOffset> = shirabe_php_shim::date_create(&date_str)?;
@@ -243,7 +243,7 @@ impl ForgejoDriver {
while let Some(url) = resource {
let response = self
.get_contents(&url, false)
- .map_err(|e| anyhow::anyhow!("{}", e.message))?;
+ .map_err(|e| anyhow::anyhow!("{}", e.get_message()))?;
let branch_data = response.decode_json()?;
if let PhpMixed::List(ref list) = branch_data {
for branch in list {
@@ -286,7 +286,7 @@ impl ForgejoDriver {
while let Some(url) = resource {
let response = self
.get_contents(&url, false)
- .map_err(|e| anyhow::anyhow!("{}", e.message))?;
+ .map_err(|e| anyhow::anyhow!("{}", e.get_message()))?;
let tags_data = response.decode_json()?;
if let PhpMixed::List(ref list) = tags_data {
for tag in list {
@@ -599,7 +599,7 @@ impl ForgejoDriver {
&mut self,
url: &str,
fetching_repo_data: bool,
- ) -> anyhow::Result<Response, TransportException> {
+ ) -> anyhow::Result<Response, Box<TransportException>> {
match self.inner.get_contents(url) {
Ok(response) => Ok(response),
Err(e) => match e.get_code() {
@@ -610,14 +610,7 @@ impl ForgejoDriver {
if !self.inner.io.is_interactive() {
self.attempt_clone_fallback()
- .map_err(|inner_e| TransportException {
- message: inner_e.to_string(),
- code: 0,
- headers: None,
- response: None,
- status_code: None,
- response_info: vec![],
- })?;
+ .map_err(|inner_e| TransportException::new(inner_e.to_string(), 0))?;
return Ok(Response::new(
"dummy".to_string(),
@@ -645,14 +638,7 @@ impl ForgejoDriver {
);
let auth_result = forgejo
.authorize_o_auth_interactively(&origin_url, message.as_deref())
- .map_err(|inner_e| TransportException {
- message: inner_e.to_string(),
- code: 0,
- headers: None,
- response: None,
- status_code: None,
- response_info: vec![],
- })?;
+ .map_err(|inner_e| TransportException::new(inner_e.to_string(), 0))?;
if let Ok(true) = auth_result {
return self.inner.get_contents(url);
@@ -734,7 +720,7 @@ impl crate::repository::vcs::VcsDriverInterface for ForgejoDriver {
match self.get_composer_information(identifier) {
Ok(info) => Ok(info.is_some()),
Err(e) => {
- if e.downcast_ref::<TransportException>().is_some() {
+ if e.is_instanceof::<TransportException>() {
Ok(false)
} else {
Err(e)
diff --git a/crates/shirabe/src/repository/vcs/fossil_driver.rs b/crates/shirabe/src/repository/vcs/fossil_driver.rs
index 1b61ed4d..3795d1ca 100644
--- a/crates/shirabe/src/repository/vcs/fossil_driver.rs
+++ b/crates/shirabe/src/repository/vcs/fossil_driver.rs
@@ -12,6 +12,7 @@ use crate::util::ProcessExecutor;
use chrono::{DateTime, FixedOffset, Utc};
use indexmap::IndexMap;
use shirabe_external_packages::composer::pcre::Preg;
+use shirabe_php_shim::Catch as _;
use shirabe_php_shim::{
PhpMixed, RuntimeException, dirname, is_dir, is_file, is_writable, php_regex,
};
@@ -77,10 +78,7 @@ impl FossilDriver {
.unwrap_or("")
.to_string();
if !Cache::is_usable(&cache_repo_dir) || !Cache::is_usable(&cache_vcs_dir) {
- return Err(RuntimeException {
- message: "FossilDriver requires a usable cache directory, and it looks like you set it to be disabled".to_string(),
- code: 0,
- }
+ return Err(RuntimeException::new("FossilDriver requires a usable cache directory, and it looks like you set it to be disabled".to_string())
.into());
}
@@ -105,13 +103,10 @@ impl FossilDriver {
None,
) != 0
{
- return Err(RuntimeException {
- message: format!(
- "fossil was not found, check that it is installed and in your PATH env.\n\n{}",
- self.inner.process.borrow().get_error_output()
- ),
- code: 0,
- }
+ return Err(RuntimeException::new(format!(
+ "fossil was not found, check that it is installed and in your PATH env.\n\n{}",
+ self.inner.process.borrow().get_error_output()
+ ))
.into());
}
Ok(())
@@ -124,13 +119,10 @@ impl FossilDriver {
fs.ensure_directory_exists(&self.checkout_dir)?;
if !is_writable(dirname(&self.checkout_dir)) {
- return Err(RuntimeException {
- message: format!(
- "Can not clone {} to access package information. The \"{}\" directory is not writable by the current user.",
- self.inner.url, self.checkout_dir
- ),
- code: 0,
- }
+ return Err(RuntimeException::new(format!(
+ "Can not clone {} to access package information. The \"{}\" directory is not writable by the current user.",
+ self.inner.url, self.checkout_dir
+ ))
.into());
}
@@ -173,13 +165,10 @@ impl FossilDriver {
) != 0
{
let output = self.inner.process.borrow().get_error_output().to_string();
- return Err(RuntimeException {
- message: format!(
- "Failed to clone {} to repository {}\n\n{}",
- self.inner.url, repo_file, output
- ),
- code: 0,
- }
+ return Err(RuntimeException::new(format!(
+ "Failed to clone {} to repository {}\n\n{}",
+ self.inner.url, repo_file, output
+ ))
.into());
}
@@ -192,13 +181,10 @@ impl FossilDriver {
) != 0
{
let output = self.inner.process.borrow().get_error_output().to_string();
- return Err(RuntimeException {
- message: format!(
- "Failed to open repository {} in {}\n\n{}",
- repo_file, self.checkout_dir, output
- ),
- code: 0,
- }
+ return Err(RuntimeException::new(format!(
+ "Failed to open repository {} in {}\n\n{}",
+ repo_file, self.checkout_dir, output
+ ))
.into());
}
}
@@ -231,13 +217,10 @@ impl FossilDriver {
pub fn get_file_content(&self, file: &str, identifier: &str) -> anyhow::Result<Option<String>> {
if identifier.starts_with('-') {
- return Err(RuntimeException {
- message: format!(
- "Invalid fossil identifier detected. Identifier must not start with a -, given: {}",
- identifier
- ),
- code: 0,
- }
+ return Err(RuntimeException::new(format!(
+ "Invalid fossil identifier detected. Identifier must not start with a -, given: {}",
+ identifier
+ ))
.into());
}
@@ -420,7 +403,7 @@ impl crate::repository::vcs::VcsDriverInterface for FossilDriver {
match self.get_composer_information(identifier) {
Ok(info) => Ok(info.is_some()),
Err(e) => {
- if e.downcast_ref::<TransportException>().is_some() {
+ if e.is_instanceof::<TransportException>() {
Ok(false)
} else {
Err(e)
diff --git a/crates/shirabe/src/repository/vcs/git_bitbucket_driver.rs b/crates/shirabe/src/repository/vcs/git_bitbucket_driver.rs
index 8fe93018..d833b576 100644
--- a/crates/shirabe/src/repository/vcs/git_bitbucket_driver.rs
+++ b/crates/shirabe/src/repository/vcs/git_bitbucket_driver.rs
@@ -16,6 +16,7 @@ use crate::util::http::Response;
use chrono::{DateTime, FixedOffset};
use indexmap::IndexMap;
use shirabe_external_packages::composer::pcre::{CaptureKey, Preg};
+use shirabe_php_shim::Catch as _;
use shirabe_php_shim::{
InvalidArgumentException, LogicException, PhpMixed, RuntimeException, array_key_exists,
array_search_mixed, extension_loaded, http_build_query_mixed, implode, is_array, php_regex,
@@ -90,13 +91,10 @@ impl GitBitbucketDriver {
&self.inner.url,
Some(&mut m),
) {
- return Err(InvalidArgumentException {
- message: format!(
- "The Bitbucket repository URL {} is invalid. It must be the HTTPS URL of a Bitbucket repository.",
- self.inner.url.clone(),
- ),
- code: 0,
- }
+ return Err(InvalidArgumentException::new(format!(
+ "The Bitbucket repository URL {} is invalid. It must be the HTTPS URL of a Bitbucket repository.",
+ self.inner.url.clone(),
+ ))
.into());
}
@@ -706,7 +704,7 @@ impl GitBitbucketDriver {
if !self.inner.io.has_authentication(&self.inner.origin_url)
&& bitbucket_util.authorize_oauth(&self.inner.origin_url)
{
- return self.inner.get_contents(url).map_err(anyhow::Error::from);
+ return self.inner.get_contents(url).map_err(|e| (*e).into());
}
if !self.inner.io.is_interactive() && fetching_repo_data {
@@ -722,7 +720,7 @@ impl GitBitbucketDriver {
}
}
- Err(e.into())
+ Err((*e).into())
}
}
}
@@ -742,7 +740,7 @@ impl GitBitbucketDriver {
match self.setup_fallback_driver(&self.generate_ssh_url()) {
Ok(()) => Ok(true),
Err(e) => {
- if e.downcast_ref::<RuntimeException>().is_some() {
+ if e.is_instanceof::<RuntimeException>() {
self.fallback_driver = None;
self.inner.io.write_error(&format!(
@@ -799,11 +797,10 @@ impl GitBitbucketDriver {
if self.root_identifier.is_none() {
if !self.get_repo_data()? {
if self.fallback_driver.is_none() {
- return Err(LogicException {
- message: "A fallback driver should be setup if getRepoData returns false"
+ return Err(LogicException::new(
+ "A fallback driver should be setup if getRepoData returns false"
.to_string(),
- code: 0,
- }
+ )
.into());
}
@@ -811,13 +808,10 @@ impl GitBitbucketDriver {
}
if self.vcs_type.as_deref() != Some("git") {
- return Err(RuntimeException {
- message: format!(
- "{} does not appear to be a git repository, use {} but remember that Bitbucket no longer supports the mercurial repositories. https://bitbucket.org/blog/sunsetting-mercurial-support-in-bitbucket",
- self.inner.url, self.clone_https_url
- ),
- code: 0,
- }
+ return Err(RuntimeException::new(format!(
+ "{} does not appear to be a git repository, use {} but remember that Bitbucket no longer supports the mercurial repositories. https://bitbucket.org/blog/sunsetting-mercurial-support-in-bitbucket",
+ self.inner.url, self.clone_https_url
+ ))
.into());
}
@@ -918,7 +912,7 @@ impl crate::repository::vcs::VcsDriverInterface for GitBitbucketDriver {
match self.get_composer_information(identifier) {
Ok(info) => Ok(info.is_some()),
Err(e) => {
- if e.downcast_ref::<TransportException>().is_some() {
+ if e.is_instanceof::<TransportException>() {
Ok(false)
} else {
Err(e)
diff --git a/crates/shirabe/src/repository/vcs/git_driver.rs b/crates/shirabe/src/repository/vcs/git_driver.rs
index 1376ebbc..9f8a6b32 100644
--- a/crates/shirabe/src/repository/vcs/git_driver.rs
+++ b/crates/shirabe/src/repository/vcs/git_driver.rs
@@ -15,6 +15,7 @@ use chrono::TimeZone;
use chrono::{DateTime, FixedOffset, Utc};
use indexmap::IndexMap;
use shirabe_external_packages::composer::pcre::{CaptureKey, Preg};
+use shirabe_php_shim::Catch as _;
use shirabe_php_shim::{
InvalidArgumentException, RuntimeException, dirname, is_dir, is_writable, realpath,
sys_get_temp_dir,
@@ -52,13 +53,10 @@ impl GitDriver {
if Filesystem::is_local_path(&self.inner.url) {
self.inner.url = Preg::replace(php_regex!(r"{[\\/]\.git/?$}"), "", &self.inner.url);
if !is_dir(&self.inner.url) {
- return Err(RuntimeException {
- message: format!(
- "Failed to read package information from {} as the path does not exist",
- self.inner.url
- ),
- code: 0,
- }
+ return Err(RuntimeException::new(format!(
+ "Failed to read package information from {} as the path does not exist",
+ self.inner.url
+ ))
.into());
}
self.repo_dir = self.inner.url.clone();
@@ -73,10 +71,7 @@ impl GitDriver {
.unwrap_or("")
.to_string();
if !Cache::is_usable(&cache_vcs_dir) {
- return Err(RuntimeException {
- message: "GitDriver requires a usable cache directory, and it looks like you set it to be disabled".to_string(),
- code: 0,
- }
+ return Err(RuntimeException::new("GitDriver requires a usable cache directory, and it looks like you set it to be disabled".to_string())
.into());
}
@@ -96,25 +91,19 @@ impl GitDriver {
fs.ensure_directory_exists(&dirname(&self.repo_dir))?;
if !is_writable(dirname(&self.repo_dir)) {
- return Err(RuntimeException {
- message: format!(
- "Can not clone {} to access package information. The \"{}\" directory is not writable by the current user.",
- self.inner.url,
- dirname(&self.repo_dir)
- ),
- code: 0,
- }
+ return Err(RuntimeException::new(format!(
+ "Can not clone {} to access package information. The \"{}\" directory is not writable by the current user.",
+ self.inner.url,
+ dirname(&self.repo_dir)
+ ))
.into());
}
if Preg::is_match(php_regex!(r"{^ssh://[^@]+@[^:]+:[^0-9]+}"), &self.inner.url) {
- return Err(InvalidArgumentException {
- message: format!(
- "The source URL {} is invalid, ssh URLs should have a port number after \":\".\nUse ssh://git@example.com:22/path or just git@example.com:path if you do not want to provide a password or custom port.",
- self.inner.url
- ),
- code: 0,
- }
+ return Err(InvalidArgumentException::new(format!(
+ "The source URL {} is invalid, ssh URLs should have a port number after \":\".\nUse ssh://git@example.com:22/path or just git@example.com:path if you do not want to provide a password or custom port.",
+ self.inner.url
+ ))
.into());
}
@@ -126,13 +115,10 @@ impl GitDriver {
);
if !git_util.sync_mirror(&self.inner.url, &self.repo_dir)? {
if !is_dir(&self.repo_dir) {
- return Err(RuntimeException {
- message: format!(
- "Failed to clone {} to read package information from it",
- self.inner.url
- ),
- code: 0,
- }
+ return Err(RuntimeException::new(format!(
+ "Failed to clone {} to read package information from it",
+ self.inner.url
+ ))
.into());
}
self.inner.io.write_error3(&format!(
@@ -250,13 +236,10 @@ impl GitDriver {
identifier: &str,
) -> anyhow::Result<Option<String>> {
if identifier.starts_with('-') {
- return Err(RuntimeException {
- message: format!(
- "Invalid git identifier detected. Identifier must not start with a -, given: {}",
- identifier
- ),
- code: 0,
- }
+ return Err(RuntimeException::new(format!(
+ "Invalid git identifier detected. Identifier must not start with a -, given: {}",
+ identifier
+ ))
.into());
}
@@ -283,13 +266,10 @@ impl GitDriver {
identifier: &str,
) -> anyhow::Result<Option<DateTime<FixedOffset>>> {
if identifier.starts_with('-') {
- return Err(RuntimeException {
- message: format!(
- "Invalid git identifier detected. Identifier must not start with a -, given: {}",
- identifier
- ),
- code: 0,
- }
+ return Err(RuntimeException::new(format!(
+ "Invalid git identifier detected. Identifier must not start with a -, given: {}",
+ identifier
+ ))
.into());
}
@@ -459,7 +439,7 @@ impl GitDriver {
) {
Ok(_) => Ok(true),
Err(e) => {
- if e.downcast_ref::<RuntimeException>().is_some() {
+ if e.is_instanceof::<RuntimeException>() {
Ok(false)
} else {
Err(e)
@@ -543,7 +523,7 @@ impl crate::repository::vcs::VcsDriverInterface for GitDriver {
match self.get_composer_information(identifier) {
Ok(info) => Ok(info.is_some()),
Err(e) => {
- if e.downcast_ref::<TransportException>().is_some() {
+ if e.is_instanceof::<TransportException>() {
Ok(false)
} else {
Err(e)
diff --git a/crates/shirabe/src/repository/vcs/github_driver.rs b/crates/shirabe/src/repository/vcs/github_driver.rs
index d656ae61..72bcc8ae 100644
--- a/crates/shirabe/src/repository/vcs/github_driver.rs
+++ b/crates/shirabe/src/repository/vcs/github_driver.rs
@@ -15,6 +15,7 @@ use crate::util::http::Response;
use chrono::{DateTime, FixedOffset};
use indexmap::IndexMap;
use shirabe_external_packages::composer::pcre::{CaptureKey, Preg};
+use shirabe_php_shim::Catch as _;
use shirabe_php_shim::{
InvalidArgumentException, PhpMixed, RuntimeException, array_diff, array_key_exists, array_map,
array_search_mixed, base64_decode, basename, empty, explode, extension_loaded, in_array_loose,
@@ -77,13 +78,10 @@ impl GitHubDriver {
&self.inner.url,
Some(&mut match_),
) {
- return Err(InvalidArgumentException {
- message: format!(
- "The GitHub repository URL {} is invalid.",
- self.inner.url.clone(),
- ),
- code: 0,
- }
+ return Err(InvalidArgumentException::new(format!(
+ "The GitHub repository URL {} is invalid.",
+ self.inner.url.clone(),
+ ))
.into());
}
@@ -737,7 +735,7 @@ impl GitHubDriver {
);
let mut resource = self
.get_contents(&resource_url, false)
- .map_err(|e| anyhow::anyhow!("{}", e.message))?
+ .map_err(|e| anyhow::anyhow!("{}", e.get_message()))?
.decode_json()?;
// The GitHub contents API only returns files up to 1MB as base64 encoded files
@@ -765,7 +763,7 @@ impl GitHubDriver {
.to_string();
resource = self
.get_contents(&git_url, false)
- .map_err(|e| anyhow::anyhow!("{}", e.message))?
+ .map_err(|e| anyhow::anyhow!("{}", e.get_message()))?
.decode_json()?;
}
@@ -789,10 +787,10 @@ impl GitHubDriver {
let content = match content {
Some(c) => String::from_utf8_lossy(&c).to_string(),
None => {
- return Err(RuntimeException {
- message: format!("Could not retrieve {} for {}", file, identifier),
- code: 0,
- }
+ return Err(RuntimeException::new(format!(
+ "Could not retrieve {} for {}",
+ file, identifier
+ ))
.into());
}
};
@@ -817,7 +815,7 @@ impl GitHubDriver {
);
let commit = self
.get_contents(&resource, false)
- .map_err(|e| anyhow::anyhow!("{}", e.message))?
+ .map_err(|e| anyhow::anyhow!("{}", e.get_message()))?
.decode_json()?;
let date_str = match commit {
@@ -853,7 +851,7 @@ impl GitHubDriver {
loop {
let response = self
.get_contents(resource.as_deref().unwrap_or(""), false)
- .map_err(|e| anyhow::anyhow!("{}", e.message))?;
+ .map_err(|e| anyhow::anyhow!("{}", e.get_message()))?;
let tags_data = response.decode_json()?;
if let PhpMixed::List(ref list) = tags_data {
for tag in list {
@@ -903,7 +901,7 @@ impl GitHubDriver {
loop {
let response = self
.get_contents(resource.as_deref().unwrap_or(""), false)
- .map_err(|e| anyhow::anyhow!("{}", e.message))?;
+ .map_err(|e| anyhow::anyhow!("{}", e.get_message()))?;
let branch_data = response.decode_json()?;
if let PhpMixed::List(ref list) = branch_data {
for branch in list {
@@ -1015,7 +1013,7 @@ impl GitHubDriver {
&mut self,
url: &str,
fetching_repo_data: bool,
- ) -> anyhow::Result<Response, TransportException> {
+ ) -> anyhow::Result<Response, Box<TransportException>> {
let response_result = self.inner.get_contents(url);
match response_result {
Ok(r) => Ok(r),
@@ -1028,7 +1026,7 @@ impl GitHubDriver {
)
.map_err(|err| TransportException::new(err.to_string(), 0))?;
- match e.code {
+ match e.get_code() {
401 | 404 => {
// try to authorize only if we are fetching the main /repos/foo/bar data, otherwise it must be a real 404
if !fetching_repo_data {
@@ -1178,10 +1176,10 @@ impl GitHubDriver {
};
}
Err(e) => {
- if e.code == 499 {
+ if e.get_code() == 499 {
self.attempt_clone_fallback(Some(&e))?;
} else {
- return Err(e.into());
+ return Err((*e).into());
}
}
}
@@ -1232,13 +1230,11 @@ impl GitHubDriver {
e: Option<&TransportException>,
) -> anyhow::Result<bool> {
if !self.allow_git_fallback {
- return Err(RuntimeException {
- message: format!(
- "Fallback to git driver disabled{}",
- e.map(|e| format!(": {}", e.message)).unwrap_or_default()
- ),
- code: 0,
- }
+ return Err(RuntimeException::new(format!(
+ "Fallback to git driver disabled{}",
+ e.map(|e| format!(": {}", e.get_message()))
+ .unwrap_or_default()
+ ))
.into());
}
@@ -1269,11 +1265,9 @@ impl GitHubDriver {
pub(crate) fn setup_git_driver(&mut self, url: &str) -> anyhow::Result<()> {
if !self.allow_git_fallback {
- return Err(RuntimeException {
- message: "Fallback to git driver disabled".to_string(),
- code: 0,
- }
- .into());
+ return Err(
+ RuntimeException::new("Fallback to git driver disabled".to_string()).into(),
+ );
}
let mut repo_config: IndexMap<String, PhpMixed> = IndexMap::new();
repo_config.insert("url".to_string(), PhpMixed::String(url.to_string()));
@@ -1377,7 +1371,7 @@ impl crate::repository::vcs::VcsDriverInterface for GitHubDriver {
match self.get_composer_information(identifier) {
Ok(info) => Ok(info.is_some()),
Err(e) => {
- if e.downcast_ref::<TransportException>().is_some() {
+ if e.is_instanceof::<TransportException>() {
Ok(false)
} else {
Err(e)
diff --git a/crates/shirabe/src/repository/vcs/gitlab_driver.rs b/crates/shirabe/src/repository/vcs/gitlab_driver.rs
index 5fe513f6..8432ed65 100644
--- a/crates/shirabe/src/repository/vcs/gitlab_driver.rs
+++ b/crates/shirabe/src/repository/vcs/gitlab_driver.rs
@@ -16,6 +16,7 @@ use crate::util::http::Response;
use chrono::{DateTime, FixedOffset};
use indexmap::IndexMap;
use shirabe_external_packages::composer::pcre::{CaptureKey, Preg};
+use shirabe_php_shim::Catch as _;
use shirabe_php_shim::{
InvalidArgumentException, LogicException, PhpMixed, RuntimeException, array_search_mixed,
array_shift, ctype_alnum, empty, explode, extension_loaded, implode, in_array_loose, is_array,
@@ -82,13 +83,10 @@ impl GitLabDriver {
pub fn initialize(&mut self) -> anyhow::Result<()> {
let mut match_: IndexMap<CaptureKey, String> = IndexMap::new();
if !Preg::is_match3(Self::URL_REGEX, &self.inner.url, Some(&mut match_)) {
- return Err(InvalidArgumentException {
- message: format!(
- "The GitLab repository URL {} is invalid. It must be the HTTP URL of a GitLab project.",
- self.inner.url.clone(),
- ),
- code: 0,
- }
+ return Err(InvalidArgumentException::new(format!(
+ "The GitLab repository URL {} is invalid. It must be the HTTP URL of a GitLab project.",
+ self.inner.url.clone(),
+ ))
.into());
}
@@ -134,13 +132,10 @@ impl GitLabDriver {
let origin = match origin {
Some(o) => o,
None => {
- return Err(LogicException {
- message: format!(
- "It should not be possible to create a gitlab driver with an unparsable origin URL ({})",
- self.inner.url
- ),
- code: 0,
- }
+ return Err(LogicException::new(format!(
+ "It should not be possible to create a gitlab driver with an unparsable origin URL ({})",
+ self.inner.url
+ ))
.into());
}
};
@@ -153,10 +148,9 @@ impl GitLabDriver {
{
// https treated as a synonym for http.
if !matches!(protocol, "git" | "http" | "https") {
- return Err(RuntimeException {
- message: "gitlab-protocol must be one of git, http.".to_string(),
- code: 0,
- }
+ return Err(RuntimeException::new(
+ "gitlab-protocol must be one of git, http.".to_string(),
+ )
.into());
}
self.protocol = if protocol == "git" {
@@ -424,8 +418,8 @@ impl GitLabDriver {
let content = match self.get_contents(&resource, false) {
Ok(response) => response.get_body().map(|s| s.to_string()),
Err(e) => {
- if e.code != 404 {
- return Err(e.into());
+ if e.get_code() != 404 {
+ return Err((*e).into());
}
return Ok(None);
@@ -617,7 +611,7 @@ impl GitLabDriver {
loop {
let response = self
.get_contents(resource.as_deref().unwrap_or(""), false)
- .map_err(|e| anyhow::anyhow!("{}", e.message))?;
+ .map_err(|e| anyhow::anyhow!("{}", e.get_message()))?;
let data = response.decode_json()?;
if let PhpMixed::List(ref list) = data {
@@ -676,7 +670,7 @@ impl GitLabDriver {
let resource = self.get_api_url();
let project = self
.get_contents(&resource, true)
- .map_err(|e| anyhow::anyhow!("{}", e.message))?
+ .map_err(|e| anyhow::anyhow!("{}", e.get_message()))?
.decode_json()?;
self.project = match project {
PhpMixed::Array(m) => Some(m),
@@ -769,7 +763,7 @@ impl GitLabDriver {
&mut self,
url: &str,
fetching_repo_data: bool,
- ) -> anyhow::Result<Response, TransportException> {
+ ) -> anyhow::Result<Response, Box<TransportException>> {
let response_result = self.inner.get_contents(url);
match response_result {
Ok(response) => {
@@ -839,21 +833,21 @@ impl GitLabDriver {
.and_then(|v| v.as_string())
== Some("disabled")
{
- return Err(TransportException::new(
+ return Err(Box::new(TransportException::new(
"The GitLab repository is disabled in the project".to_string(),
400,
- ));
+ )));
}
if !empty(&json_map.get("id").cloned().unwrap_or(PhpMixed::Null)) {
self.is_private = false;
}
- return Err(TransportException::new(
+ return Err(Box::new(TransportException::new(
"GitLab API seems to not be authenticated as it did not return a default_branch"
.to_string(),
401,
- ));
+ )));
}
}
@@ -868,7 +862,7 @@ impl GitLabDriver {
)
.map_err(|err| TransportException::new(err.to_string(), 0))?;
- match e.code {
+ match e.get_code() {
401 | 404 => {
// try to authorize only if we are fetching the main /repos/foo/bar data, otherwise it must be a real 404
if !fetching_repo_data {
@@ -901,7 +895,9 @@ impl GitLabDriver {
self.inner.io.write_error3(
&format!(
"<warning>Failed to download {}/{}:{}</warning>",
- self.namespace, self.repository, e.message
+ self.namespace,
+ self.repository,
+ e.get_message()
),
true,
io_interface::NORMAL,
@@ -1142,7 +1138,7 @@ impl crate::repository::vcs::VcsDriverInterface for GitLabDriver {
match self.get_composer_information(identifier) {
Ok(info) => Ok(info.is_some()),
Err(e) => {
- if e.downcast_ref::<TransportException>().is_some() {
+ if e.is_instanceof::<TransportException>() {
Ok(false)
} else {
Err(e)
diff --git a/crates/shirabe/src/repository/vcs/hg_driver.rs b/crates/shirabe/src/repository/vcs/hg_driver.rs
index 0283ed38..41aeebd9 100644
--- a/crates/shirabe/src/repository/vcs/hg_driver.rs
+++ b/crates/shirabe/src/repository/vcs/hg_driver.rs
@@ -12,6 +12,7 @@ use crate::util::Url;
use chrono::{DateTime, FixedOffset, Utc};
use indexmap::IndexMap;
use shirabe_external_packages::composer::pcre::{CaptureKey, Preg};
+use shirabe_php_shim::Catch as _;
use shirabe_php_shim::{PhpMixed, RuntimeException, dirname, is_dir, is_writable, php_regex};
#[derive(Debug)]
@@ -53,10 +54,7 @@ impl HgDriver {
.unwrap_or("")
.to_string();
if !Cache::is_usable(&cache_vcs_dir) {
- return Err(RuntimeException {
- message: "HgDriver requires a usable cache directory, and it looks like you set it to be disabled".to_string(),
- code: 0,
- }.into());
+ return Err(RuntimeException::new("HgDriver requires a usable cache directory, and it looks like you set it to be disabled".to_string()).into());
}
let sanitized = Preg::replace(
@@ -70,13 +68,10 @@ impl HgDriver {
fs.ensure_directory_exists(&cache_vcs_dir)?;
if !is_writable(dirname(&self.repo_dir)) {
- return Err(RuntimeException {
- message: format!(
- "Can not clone {} to access package information. The \"{}\" directory is not writable by the current user.",
- self.inner.url, cache_vcs_dir
- ),
- code: 0,
- }.into());
+ return Err(RuntimeException::new(format!(
+ "Can not clone {} to access package information. The \"{}\" directory is not writable by the current user.",
+ self.inner.url, cache_vcs_dir
+ )).into());
}
self.inner.config.borrow_mut().prohibit_url_by_config(
@@ -167,13 +162,10 @@ impl HgDriver {
pub fn get_file_content(&self, file: &str, identifier: &str) -> anyhow::Result<Option<String>> {
if identifier.starts_with('-') {
- return Err(RuntimeException {
- message: format!(
- "Invalid hg identifier detected. Identifier must not start with a -, given: {}",
- identifier
- ),
- code: 0,
- }
+ return Err(RuntimeException::new(format!(
+ "Invalid hg identifier detected. Identifier must not start with a -, given: {}",
+ identifier
+ ))
.into());
}
@@ -203,13 +195,10 @@ impl HgDriver {
identifier: &str,
) -> anyhow::Result<Option<DateTime<FixedOffset>>> {
if identifier.starts_with('-') {
- return Err(RuntimeException {
- message: format!(
- "Invalid hg identifier detected. Identifier must not start with a -, given: {}",
- identifier
- ),
- code: 0,
- }
+ return Err(RuntimeException::new(format!(
+ "Invalid hg identifier detected. Identifier must not start with a -, given: {}",
+ identifier
+ ))
.into());
}
@@ -443,7 +432,7 @@ impl crate::repository::vcs::VcsDriverInterface for HgDriver {
match self.get_composer_information(identifier) {
Ok(info) => Ok(info.is_some()),
Err(e) => {
- if e.downcast_ref::<TransportException>().is_some() {
+ if e.is_instanceof::<TransportException>() {
Ok(false)
} else {
Err(e)
diff --git a/crates/shirabe/src/repository/vcs/perforce_driver.rs b/crates/shirabe/src/repository/vcs/perforce_driver.rs
index 452ac5a2..af16cd8c 100644
--- a/crates/shirabe/src/repository/vcs/perforce_driver.rs
+++ b/crates/shirabe/src/repository/vcs/perforce_driver.rs
@@ -79,10 +79,7 @@ impl PerforceDriver {
.unwrap_or("")
.to_string();
if !Cache::is_usable(&cache_vcs_dir) {
- return Err(RuntimeException {
- message: "PerforceDriver requires a usable cache directory, and it looks like you set it to be disabled".to_string(),
- code: 0,
- }.into());
+ return Err(RuntimeException::new("PerforceDriver requires a usable cache directory, and it looks like you set it to be disabled".to_string()).into());
}
let repo_dir = format!("{}/{}", cache_vcs_dir, self.depot);
@@ -180,11 +177,10 @@ impl PerforceDriver {
}
pub fn get_contents(&self, _url: &str) -> anyhow::Result<Response> {
- Err(BadMethodCallException {
- message: "Not implemented/used in PerforceDriver".to_string(),
- code: 0,
- }
- .into())
+ Err(
+ BadMethodCallException::new("Not implemented/used in PerforceDriver".to_string())
+ .into(),
+ )
}
pub fn supports(
diff --git a/crates/shirabe/src/repository/vcs/svn_driver.rs b/crates/shirabe/src/repository/vcs/svn_driver.rs
index 716b1943..84e3a20d 100644
--- a/crates/shirabe/src/repository/vcs/svn_driver.rs
+++ b/crates/shirabe/src/repository/vcs/svn_driver.rs
@@ -14,6 +14,7 @@ use crate::util::Url;
use chrono::{DateTime, FixedOffset, Utc};
use indexmap::IndexMap;
use shirabe_external_packages::composer::pcre::{CaptureKey, Preg};
+use shirabe_php_shim::Catch as _;
use shirabe_php_shim::{
PhpMixed, RuntimeException, php_regex, stripos, strrpos, strtr, substr, trim,
};
@@ -199,14 +200,14 @@ impl SvnDriver {
Ok(c) => c,
Err(e) => {
// PHP catches only TransportException; other exceptions propagate uncaught.
- if e.downcast_ref::<TransportException>().is_none() {
+ if !e.is_instanceof::<TransportException>() {
return Err(e);
}
let message = e
- .downcast_ref::<TransportException>()
+ .catch::<TransportException>()
.unwrap()
- .message
- .clone();
+ .get_message()
+ .to_string();
if stripos(&message, "path not found").is_none()
&& stripos(&message, "svn: warning: W160013").is_none()
{
@@ -277,8 +278,8 @@ impl SvnDriver {
) {
Ok(o) => o,
Err(e) => {
- if let Some(e) = e.downcast_ref::<RuntimeException>() {
- return Err(TransportException::new(e.message.clone(), 0).into());
+ if let Some(e) = e.catch::<RuntimeException>() {
+ return Err(TransportException::new(e.get_message().to_string(), 0).into());
}
return Err(e);
}
@@ -567,24 +568,18 @@ impl SvnDriver {
Ok(o) => Ok(o),
Err(e) => {
if self.util.as_mut().unwrap().binary_version().is_none() {
- return Err(RuntimeException {
- message: format!(
- "Failed to load {}, svn was not found, check that it is installed and in your PATH env.\n\n{}",
- self.inner.url,
- self.inner.process.borrow().get_error_output(),
- ),
- code: 0,
- }
+ return Err(RuntimeException::new(format!(
+ "Failed to load {}, svn was not found, check that it is installed and in your PATH env.\n\n{}",
+ self.inner.url,
+ self.inner.process.borrow().get_error_output(),
+ ))
.into());
}
- Err(RuntimeException {
- message: format!(
- "Repository {} could not be processed, {}",
- self.inner.url, e,
- ),
- code: 0,
- }
+ Err(RuntimeException::new(format!(
+ "Repository {} could not be processed, {}",
+ self.inner.url, e,
+ ))
.into())
}
}
@@ -655,7 +650,7 @@ impl crate::repository::vcs::VcsDriverInterface for SvnDriver {
match self.get_composer_information(identifier) {
Ok(info) => Ok(info.is_some()),
Err(e) => {
- if e.downcast_ref::<TransportException>().is_some() {
+ if e.is_instanceof::<TransportException>() {
Ok(false)
} else {
Err(e)
diff --git a/crates/shirabe/src/repository/vcs/vcs_driver.rs b/crates/shirabe/src/repository/vcs/vcs_driver.rs
index 3321201c..42f679df 100644
--- a/crates/shirabe/src/repository/vcs/vcs_driver.rs
+++ b/crates/shirabe/src/repository/vcs/vcs_driver.rs
@@ -13,6 +13,7 @@ use crate::util::http::Response;
use chrono::{DateTime, FixedOffset};
use indexmap::IndexMap;
use shirabe_external_packages::composer::pcre::Preg;
+use shirabe_php_shim::Catch as _;
use shirabe_php_shim::{DATE_RFC3339, PhpMixed, extension_loaded, php_regex};
#[derive(Debug)]
@@ -66,7 +67,7 @@ impl VcsDriverBase {
"http"
}
- pub fn get_contents(&self, url: &str) -> anyhow::Result<Response, TransportException> {
+ pub fn get_contents(&self, url: &str) -> anyhow::Result<Response, Box<TransportException>> {
let options_mixed = self
.repo_config
.get("options")
@@ -79,9 +80,11 @@ impl VcsDriverBase {
self.http_downloader
.borrow_mut()
.get(url, options)
- .map_err(|e| match e.downcast::<TransportException>() {
- Ok(te) => te,
- Err(other) => TransportException::new(other.to_string(), 0),
+ .map_err(|e| {
+ Box::new(match e.catch::<TransportException>() {
+ Some(te) => te.clone(),
+ None => TransportException::new(e.to_string(), 0),
+ })
})
}
@@ -299,7 +302,7 @@ pub trait VcsDriver: VcsDriverInterface {
"http"
}
- fn get_contents(&self, url: &str) -> anyhow::Result<Response, TransportException> {
+ fn get_contents(&self, url: &str) -> anyhow::Result<Response, Box<TransportException>> {
let options_mixed = self
.repo_config()
.get("options")
@@ -312,9 +315,11 @@ pub trait VcsDriver: VcsDriverInterface {
self.http_downloader()
.borrow_mut()
.get(url, options)
- .map_err(|e| match e.downcast::<TransportException>() {
- Ok(te) => te,
- Err(other) => TransportException::new(other.to_string(), 0),
+ .map_err(|e| {
+ Box::new(match e.catch::<TransportException>() {
+ Some(te) => te.clone(),
+ None => TransportException::new(e.to_string(), 0),
+ })
})
}
diff --git a/crates/shirabe/src/repository/vcs_repository.rs b/crates/shirabe/src/repository/vcs_repository.rs
index 521d7aea..2b811c78 100644
--- a/crates/shirabe/src/repository/vcs_repository.rs
+++ b/crates/shirabe/src/repository/vcs_repository.rs
@@ -28,6 +28,7 @@ use crate::util::ProcessExecutor;
use crate::util::Url;
use indexmap::IndexMap;
use shirabe_external_packages::composer::pcre::Preg;
+use shirabe_php_shim::Catch as _;
use shirabe_php_shim::{
InvalidArgumentException, PhpClass, PhpMixed, php_regex, str_replace, strpos,
};
@@ -305,10 +306,10 @@ impl VcsRepository {
let driver_url = self.url.clone();
self.ensure_driver();
if self.driver.borrow().is_none() {
- return Err(InvalidArgumentException {
- message: format!("No driver found to handle VCS repository {}", driver_url),
- code: 0,
- }
+ return Err(InvalidArgumentException::new(format!(
+ "No driver found to handle VCS repository {}",
+ driver_url
+ ))
.into());
}
*self.version_parser.borrow_mut() = Some(VersionParser::new());
@@ -351,7 +352,7 @@ impl VcsRepository {
}
Ok(None) => {}
Err(e) => {
- if let Some(te) = e.downcast_ref::<TransportException>()
+ if let Some(te) = e.catch::<TransportException>()
&& self.should_rethrow_transport_exception(te)
{
return Err(e);
@@ -367,7 +368,7 @@ impl VcsRepository {
}
}
Err(e) => {
- if let Some(te) = e.downcast_ref::<TransportException>()
+ if let Some(te) = e.catch::<TransportException>()
&& self.should_rethrow_transport_exception(te)
{
return Err(e);
@@ -575,7 +576,7 @@ impl VcsRepository {
Ok(())
})();
if let Err(e) = result {
- if let Some(te) = e.downcast_ref::<TransportException>() {
+ if let Some(te) = e.catch::<TransportException>() {
self.version_transport_exceptions
.borrow_mut()
.entry("tags".to_string())
@@ -589,7 +590,7 @@ impl VcsRepository {
}
}
if is_very_verbose {
- let detail = if let Some(te) = e.downcast_ref::<TransportException>() {
+ let detail = if let Some(te) = e.catch::<TransportException>() {
format!(
"no composer file was found ({} HTTP status code)",
te.get_code()
@@ -786,7 +787,7 @@ impl VcsRepository {
Ok(())
})();
if let Err(e) = result {
- if let Some(te) = e.downcast_ref::<TransportException>() {
+ if let Some(te) = e.catch::<TransportException>() {
self.version_transport_exceptions
.borrow_mut()
.entry("branches".to_string())
diff --git a/crates/shirabe/src/self_update/versions.rs b/crates/shirabe/src/self_update/versions.rs
index 14ad10d8..d3611ede 100644
--- a/crates/shirabe/src/self_update/versions.rs
+++ b/crates/shirabe/src/self_update/versions.rs
@@ -73,14 +73,11 @@ impl Versions {
io: Option<std::rc::Rc<std::cell::RefCell<dyn IOInterface>>>,
) -> anyhow::Result<Result<(), InvalidArgumentException>> {
if !Self::CHANNELS.contains(&channel.as_str()) {
- return Ok(Err(InvalidArgumentException {
- message: format!(
- "Invalid channel {}, must be one of: {}",
- channel,
- Self::CHANNELS.join(", ")
- ),
- code: 0,
- }));
+ return Ok(Err(InvalidArgumentException::new(format!(
+ "Invalid channel {}, must be one of: {}",
+ channel,
+ Self::CHANNELS.join(", ")
+ ))));
}
let channel_file = format!(
@@ -146,13 +143,10 @@ impl Versions {
}
}
- Ok(Err(UnexpectedValueException {
- message: format!(
- "There is no version of Composer available for your PHP version ({})",
- PHP_VERSION
- ),
- code: 0,
- }))
+ Ok(Err(UnexpectedValueException::new(format!(
+ "There is no version of Composer available for your PHP version ({})",
+ PHP_VERSION
+ ))))
}
fn get_versions_data(&mut self) -> anyhow::Result<PhpMixed> {
diff --git a/crates/shirabe/src/util/auth_helper.rs b/crates/shirabe/src/util/auth_helper.rs
index a323c37e..69a84857 100644
--- a/crates/shirabe/src/util/auth_helper.rs
+++ b/crates/shirabe/src/util/auth_helper.rs
@@ -80,11 +80,7 @@ impl AuthHelper {
) {
return Ok(PhpMixed::String(input));
}
- Err(RuntimeException {
- message: "Please answer (y)es or (n)o".to_string(),
- code: 0,
- }
- .into())
+ Err(RuntimeException::new("Please answer (y)es or (n)o".to_string()).into())
}),
None,
PhpMixed::String("y".to_string()),
diff --git a/crates/shirabe/src/util/bitbucket.rs b/crates/shirabe/src/util/bitbucket.rs
index 50d4b700..d8e245a9 100644
--- a/crates/shirabe/src/util/bitbucket.rs
+++ b/crates/shirabe/src/util/bitbucket.rs
@@ -9,10 +9,11 @@ use crate::io::io_interface;
use crate::util::HttpDownloader;
use crate::util::ProcessExecutor;
use indexmap::IndexMap;
+use shirabe_php_shim::Catch as _;
use shirabe_php_shim::{LogicException, PhpMixed, time};
fn transport_error_code(err: &anyhow::Error) -> Option<i64> {
- err.downcast_ref::<TransportException>().map(|te| te.code)
+ err.catch::<TransportException>().map(|te| te.get_code())
}
#[derive(Debug)]
@@ -167,24 +168,18 @@ impl Bitbucket {
let token_map = match token {
PhpMixed::Array(ref m) => m.clone(),
_ => {
- return Err(LogicException {
- message: format!(
- "Expected a token configured with expires_in and access_token present, got {}",
- shirabe_php_shim::json_encode(&token).unwrap_or_default()
- ),
- code: 0,
- }
+ return Err(LogicException::new(format!(
+ "Expected a token configured with expires_in and access_token present, got {}",
+ shirabe_php_shim::json_encode(&token).unwrap_or_default()
+ ))
.into());
}
};
if !token_map.contains_key("expires_in") || !token_map.contains_key("access_token") {
- return Err(LogicException {
- message: format!(
- "Expected a token configured with expires_in and access_token present, got {}",
- shirabe_php_shim::json_encode(&token).unwrap_or_default()
- ),
- code: 0,
- }
+ return Err(LogicException::new(format!(
+ "Expected a token configured with expires_in and access_token present, got {}",
+ shirabe_php_shim::json_encode(&token).unwrap_or_default()
+ ))
.into());
}
self.token = Some(token_map.into_iter().collect());
@@ -350,11 +345,7 @@ impl Bitbucket {
match access_token {
Some(t) => Ok(t),
- None => Err(LogicException {
- message: "Failed to initialize token above".to_string(),
- code: 0,
- }
- .into()),
+ None => Err(LogicException::new("Failed to initialize token above".to_string()).into()),
}
}
@@ -370,9 +361,10 @@ impl Bitbucket {
.get_config_source_mut()
.remove_config_setting(&format!("bitbucket-oauth.{}", origin_url))?;
- let token = self.token.as_ref().ok_or_else(|| LogicException {
- message: "Expected a token configured with expires_in present, got null".to_string(),
- code: 0,
+ let token = self.token.as_ref().ok_or_else(|| {
+ LogicException::new(
+ "Expected a token configured with expires_in present, got null".to_string(),
+ )
})?;
let expires_in = token
.get("expires_in")
@@ -380,13 +372,10 @@ impl Bitbucket {
.ok_or_else(|| {
let token_mixed =
PhpMixed::Array(token.iter().map(|(k, v)| (k.clone(), v.clone())).collect());
- LogicException {
- message: format!(
- "Expected a token configured with expires_in present, got {}",
- shirabe_php_shim::json_encode(&token_mixed).unwrap_or_default()
- ),
- code: 0,
- }
+ LogicException::new(format!(
+ "Expected a token configured with expires_in present, got {}",
+ shirabe_php_shim::json_encode(&token_mixed).unwrap_or_default()
+ ))
})?;
let t = self.time.unwrap_or_else(time);
diff --git a/crates/shirabe/src/util/config_validator.rs b/crates/shirabe/src/util/config_validator.rs
index 9b6b292d..978a5cd2 100644
--- a/crates/shirabe/src/util/config_validator.rs
+++ b/crates/shirabe/src/util/config_validator.rs
@@ -10,6 +10,7 @@ use crate::package::loader::ValidatingArrayLoader;
use indexmap::IndexMap;
use serde::de::Error as _;
use shirabe_external_packages::composer::pcre::Preg;
+use shirabe_php_shim::Catch as _;
use shirabe_php_shim::{PhpMixed, php_regex};
use shirabe_spdx_licenses::SpdxLicenses;
@@ -55,7 +56,7 @@ impl ConfigValidator {
match schema_result {
Ok(()) => {}
Err(e) => {
- if let Some(validation_e) = e.downcast_ref::<JsonValidationException>() {
+ if let Some(validation_e) = e.catch::<JsonValidationException>() {
for message in validation_e.get_errors() {
if lax_valid {
publish_errors.push(message.clone());
@@ -298,7 +299,7 @@ impl ConfigValidator {
) {
Ok(_) => {}
Err(e) => {
- if let Some(invalid_e) = e.downcast_ref::<InvalidPackageException>() {
+ if let Some(invalid_e) = e.catch::<InvalidPackageException>() {
errors.extend_from_slice(invalid_e.get_errors());
}
}
diff --git a/crates/shirabe/src/util/error_handler.rs b/crates/shirabe/src/util/error_handler.rs
index 2e574fe0..dcea940e 100644
--- a/crates/shirabe/src/util/error_handler.rs
+++ b/crates/shirabe/src/util/error_handler.rs
@@ -58,13 +58,7 @@ impl ErrorHandler {
return Ok(true);
}
- return Err(ErrorException {
- message,
- code: 0,
- severity: level,
- filename: file,
- lineno: line,
- });
+ return Err(ErrorException::new(message, 0, level, file, line, None));
}
let io = IO.with(|cell| cell.borrow().clone());
diff --git a/crates/shirabe/src/util/filesystem.rs b/crates/shirabe/src/util/filesystem.rs
index daf26e22..7010fd86 100644
--- a/crates/shirabe/src/util/filesystem.rs
+++ b/crates/shirabe/src/util/filesystem.rs
@@ -124,9 +124,11 @@ impl Filesystem {
// `rm -rf`/`rmdir` subprocess via the String-based ProcessExecutor, so it has to be
// representable as UTF-8.
let directory = directory.as_ref();
- let directory = directory.to_str().ok_or_else(|| RuntimeException {
- message: format!("Path contains invalid UTF-8: {}", directory.display()),
- code: 0,
+ let directory = directory.to_str().ok_or_else(|| {
+ RuntimeException::new(format!(
+ "Path contains invalid UTF-8: {}",
+ directory.display()
+ ))
})?;
let edge_case_result = self.remove_edge_cases(directory, true)?;
if let Some(r) = edge_case_result {
@@ -246,10 +248,7 @@ impl Filesystem {
}
if Preg::is_match3(php_regex!("{^(?:[a-z]:)?[/\\\\]+$}i"), directory, None) {
- return Err(RuntimeException {
- message: format!("Aborting an attempted deletion of {}, this was probably not intended, if it is a real use case please report it.", directory),
- code: 0,
- }
+ return Err(RuntimeException::new(format!("Aborting an attempted deletion of {}, this was probably not intended, if it is a real use case please report it.", directory))
.into());
}
@@ -309,42 +308,36 @@ impl Filesystem {
pub fn ensure_directory_exists(&mut self, directory: &str) -> anyhow::Result<()> {
if !is_dir(directory) {
if file_exists(directory) {
- return Err(RuntimeException {
- message: format!("{} exists and is not a directory.", directory),
- code: 0,
- }
+ return Err(RuntimeException::new(format!(
+ "{} exists and is not a directory.",
+ directory
+ ))
.into());
}
if is_link(directory) && !self.unlink_implementation(Path::new(directory)) {
- return Err(RuntimeException {
- message: format!(
- "Could not delete symbolic link {}: {}",
- directory,
- error_get_last()
- .as_ref()
- .and_then(|m| m.get("message"))
- .and_then(|v| v.as_string())
- .unwrap_or("")
- ),
- code: 0,
- }
+ return Err(RuntimeException::new(format!(
+ "Could not delete symbolic link {}: {}",
+ directory,
+ error_get_last()
+ .as_ref()
+ .and_then(|m| m.get("message"))
+ .and_then(|v| v.as_string())
+ .unwrap_or("")
+ ))
.into());
}
if !mkdir(directory, 0o777, true) {
- let e = RuntimeException {
- message: format!(
- "{} does not exist and could not be created: {}",
- directory,
- error_get_last()
- .as_ref()
- .and_then(|m| m.get("message"))
- .and_then(|v| v.as_string())
- .unwrap_or("")
- ),
- code: 0,
- };
+ let e = RuntimeException::new(format!(
+ "{} does not exist and could not be created: {}",
+ directory,
+ error_get_last()
+ .as_ref()
+ .and_then(|m| m.get("message"))
+ .and_then(|v| v.as_string())
+ .unwrap_or("")
+ ));
// in pathological cases with paths like path/to/broken-symlink/../foo is_dir will fail to detect path/to/foo
// but normalizing the ../ away first makes it work so we attempt this just in case, and if it still fails we
@@ -390,7 +383,7 @@ impl Filesystem {
message.push_str("\nThis can be due to an antivirus or the Windows Search Indexer locking the file while they are analyzed");
}
- return Err(RuntimeException { message, code: 0 }.into());
+ return Err(RuntimeException::new(message).into());
}
}
@@ -423,7 +416,7 @@ impl Filesystem {
message.push_str("\nThis can be due to an antivirus or the Windows Search Indexer locking the file while they are analyzed");
}
- return Err(RuntimeException { message, code: 0 }.into());
+ return Err(RuntimeException::new(message).into());
}
}
@@ -464,7 +457,7 @@ impl Filesystem {
// if copy fails we attempt to copy it manually as this can help bypass issues with VirtualBox shared folders
// see https://github.com/composer/composer/issues/12057
- if str_contains(&e.message, "Bad address") {
+ if str_contains(e.get_message(), "Bad address") {
let (source_handle, target_handle) =
match (fopen(source, "r"), fopen(&target, "w")) {
(Ok(source_handle), Ok(target_handle)) => {
@@ -520,13 +513,11 @@ impl Filesystem {
// TODO(phase-c):
// The fallbacks below (copy_then_remove and the mv/xcopy subprocesses) operate on
// path strings, so beyond this point the paths have to be representable as UTF-8.
- let source = source.to_str().ok_or_else(|| RuntimeException {
- message: format!("Path contains invalid UTF-8: {}", source.display()),
- code: 0,
+ let source = source.to_str().ok_or_else(|| {
+ RuntimeException::new(format!("Path contains invalid UTF-8: {}", source.display()))
})?;
- let target = target.to_str().ok_or_else(|| RuntimeException {
- message: format!("Path contains invalid UTF-8: {}", target.display()),
- code: 0,
+ let target = target.to_str().ok_or_else(|| {
+ RuntimeException::new(format!("Path contains invalid UTF-8: {}", target.display()))
})?;
if !function_exists("proc_open") {
@@ -735,11 +726,9 @@ impl Filesystem {
pub fn size(&self, path: impl AsRef<Path>) -> anyhow::Result<i64> {
let path = path.as_ref();
if !file_exists(path) {
- return Err(RuntimeException {
- message: format!("{} does not exist.", path.display()),
- code: 0,
- }
- .into());
+ return Err(
+ RuntimeException::new(format!("{} does not exist.", path.display())).into(),
+ );
}
if is_dir(path) {
return self.directory_size(path);
@@ -987,13 +976,10 @@ impl Filesystem {
/// Creates an NTFS junction.
pub fn junction(&mut self, target: &str, junction: &str) -> anyhow::Result<()> {
if !Platform::is_windows() {
- return Err(LogicException {
- message: format!(
- "Function {} is not available on non-Windows platform",
- "Composer\\Util\\Filesystem"
- ),
- code: 0,
- }
+ return Err(LogicException::new(format!(
+ "Function {} is not available on non-Windows platform",
+ "Composer\\Util\\Filesystem"
+ ))
.into());
}
if !is_dir(target) {
diff --git a/crates/shirabe/src/util/forgejo.rs b/crates/shirabe/src/util/forgejo.rs
index 34d44b7b..6c18e4f6 100644
--- a/crates/shirabe/src/util/forgejo.rs
+++ b/crates/shirabe/src/util/forgejo.rs
@@ -6,6 +6,7 @@ use crate::io::IOInterface;
use crate::io::IOInterfaceImmutable;
use crate::io::io_interface;
use crate::util::HttpDownloader;
+use shirabe_php_shim::Catch as _;
#[derive(Debug)]
pub struct Forgejo {
@@ -121,8 +122,8 @@ impl Forgejo {
Ok(_) => {}
Err(e) => {
let code = e
- .downcast_ref::<crate::downloader::TransportException>()
- .map(|te| te.code)
+ .catch::<crate::downloader::TransportException>()
+ .map(|te| te.get_code())
.unwrap_or(0);
if [403, 401, 404].contains(&code) {
self.io.write_error3(
diff --git a/crates/shirabe/src/util/forgejo_url.rs b/crates/shirabe/src/util/forgejo_url.rs
index ce5a8948..639426e1 100644
--- a/crates/shirabe/src/util/forgejo_url.rs
+++ b/crates/shirabe/src/util/forgejo_url.rs
@@ -27,10 +27,10 @@ impl ForgejoUrl {
pub fn create(repo_url: &str) -> anyhow::Result<Self> {
match Self::try_from(Some(repo_url)) {
Some(url) => Ok(url),
- None => Err(InvalidArgumentException {
- message: format!("This is not a valid Forgejo URL: {}", repo_url),
- code: 0,
- }
+ None => Err(InvalidArgumentException::new(format!(
+ "This is not a valid Forgejo URL: {}",
+ repo_url
+ ))
.into()),
}
}
diff --git a/crates/shirabe/src/util/git.rs b/crates/shirabe/src/util/git.rs
index a6f8d79e..3eec0947 100644
--- a/crates/shirabe/src/util/git.rs
+++ b/crates/shirabe/src/util/git.rs
@@ -64,11 +64,7 @@ impl Git {
);
match io {
None => {
- return Err(RuntimeException {
- message: msg,
- code: 0,
- }
- .into());
+ return Err(RuntimeException::new(msg).into());
}
Some(io) => {
io.write_error3(
@@ -215,13 +211,10 @@ impl Git {
};
if Preg::is_match(php_regex!(r"{^ssh://[^@]+@[^:]+:[^0-9]+}"), url) {
- return Err(InvalidArgumentException {
- message: format!(
- "The source URL {} is invalid, ssh URLs should have a port number after \":\".\nUse ssh://git@example.com:22/path or just git@example.com:path if you do not want to provide a password or custom port.",
- url
- ),
- code: 0,
- }
+ return Err(InvalidArgumentException::new(format!(
+ "The source URL {} is invalid, ssh URLs should have a port number after \":\".\nUse ssh://git@example.com:22/path or just git@example.com:path if you do not want to provide a password or custom port.",
+ url
+ ))
.into());
}
@@ -1277,22 +1270,15 @@ impl Git {
Option::<&str>::None,
) != 0
{
- return Err(RuntimeException {
- message: Url::sanitize(format!(
- "Failed to clone {}, git was not found, check that it is installed and in your PATH env.\n\n{}",
- url,
- self.process.borrow().get_error_output()
- )),
- code: 0,
- }
+ return Err(RuntimeException::new(Url::sanitize(format!(
+ "Failed to clone {}, git was not found, check that it is installed and in your PATH env.\n\n{}",
+ url,
+ self.process.borrow().get_error_output()
+ )))
.into());
}
- Err(RuntimeException {
- message: Url::sanitize(message.to_string()),
- code: 0,
- }
- .into())
+ Err(RuntimeException::new(Url::sanitize(message.to_string())).into())
}
/// Retrieves the current git version.
diff --git a/crates/shirabe/src/util/github.rs b/crates/shirabe/src/util/github.rs
index 01a5dd1f..066f0ff5 100644
--- a/crates/shirabe/src/util/github.rs
+++ b/crates/shirabe/src/util/github.rs
@@ -9,6 +9,7 @@ use crate::util::HttpDownloader;
use crate::util::ProcessExecutor;
use indexmap::IndexMap;
use shirabe_external_packages::composer::pcre::{CaptureKey, Preg};
+use shirabe_php_shim::Catch as _;
use shirabe_php_shim::{PhpMixed, date, in_array_loose, php_regex, stripos, strtolower};
#[derive(Debug)]
@@ -233,7 +234,7 @@ impl GitHub {
Ok(_) => {}
Err(te) => {
let code = te
- .downcast_ref::<crate::downloader::TransportException>()
+ .catch::<crate::downloader::TransportException>()
.map(|t| t.get_code())
.unwrap_or(0);
if code == 403 || code == 401 {
diff --git a/crates/shirabe/src/util/gitlab.rs b/crates/shirabe/src/util/gitlab.rs
index c14ad46a..cdeb0f21 100644
--- a/crates/shirabe/src/util/gitlab.rs
+++ b/crates/shirabe/src/util/gitlab.rs
@@ -10,6 +10,7 @@ use crate::util::HttpDownloader;
use crate::util::ProcessExecutor;
use indexmap::IndexMap;
use shirabe_external_packages::composer::pcre::Preg;
+use shirabe_php_shim::Catch as _;
use shirabe_php_shim::{
PhpMixed, RuntimeException, http_build_query, in_array_strict, json_decode, php_regex, time,
};
@@ -248,9 +249,9 @@ impl GitLab {
Err(e) => {
// 401 is bad credentials,
// 403 is max login attempts exceeded
- match e.downcast::<TransportException>() {
- Ok(te) if te.code == 403 || te.code == 401 => {
- if te.code == 401 {
+ match e.catch::<TransportException>() {
+ Some(te) if te.get_code() == 403 || te.get_code() == 401 => {
+ if te.get_code() == 401 {
let response =
te.get_response().and_then(|r| json_decode(r, true).ok());
let is_invalid_grant = response
@@ -301,8 +302,7 @@ impl GitLab {
continue;
}
- Ok(te) => return Err(te.into()),
- Err(e) => return Err(e),
+ _ => return Err(e),
}
}
};
@@ -360,10 +360,9 @@ impl GitLab {
return Ok(true);
}
- Err(RuntimeException {
- message: "Invalid GitLab credentials 5 times in a row, aborting.".to_string(),
- code: 0,
- }
+ Err(RuntimeException::new(
+ "Invalid GitLab credentials 5 times in a row, aborting.".to_string(),
+ )
.into())
}
@@ -374,16 +373,17 @@ impl GitLab {
) -> anyhow::Result<bool> {
let response = match self.refresh_token(scheme, origin_url) {
Ok(r) => r,
- Err(e) => match e.downcast::<TransportException>() {
- Ok(te) => {
+ Err(e) => match e.catch::<TransportException>() {
+ Some(te) => {
+ let message = te.get_message().to_string();
self.io.write_error3(
- &format!("Couldn't refresh access token: {}", te.message),
+ &format!("Couldn't refresh access token: {}", message),
true,
io_interface::NORMAL,
);
return Ok(false);
}
- Err(e) => return Err(e),
+ None => return Err(e),
},
};
@@ -488,10 +488,10 @@ impl GitLab {
let refresh_token = match refresh_token {
Some(t) => t,
None => {
- return Err(RuntimeException {
- message: format!("No GitLab refresh token present for {}.", origin_url),
- code: 0,
- }
+ return Err(RuntimeException::new(format!(
+ "No GitLab refresh token present for {}.",
+ origin_url
+ ))
.into());
}
};
diff --git a/crates/shirabe/src/util/http/curl_downloader.rs b/crates/shirabe/src/util/http/curl_downloader.rs
index 604dae77..6409c9d5 100644
--- a/crates/shirabe/src/util/http/curl_downloader.rs
+++ b/crates/shirabe/src/util/http/curl_downloader.rs
@@ -60,7 +60,7 @@ static TIMEOUT_WARNING: AtomicBool = AtomicBool::new(false);
enum Decision {
Retry { url: String, delay_ms: Option<u64> },
Done(Response),
- Failed(TransportException),
+ Failed(anyhow::Error),
}
impl CurlDownloader {
@@ -108,7 +108,7 @@ impl CurlDownloader {
url: &str,
mut options: IndexMap<String, PhpMixed>,
copy_to: Option<&str>,
- ) -> anyhow::Result<Result<Response, TransportException>> {
+ ) -> anyhow::Result<Result<Response, anyhow::Error>> {
let mut attributes: IndexMap<String, PhpMixed> = {
let mut m = IndexMap::new();
m.insert("retryAuthFailure".to_string(), PhpMixed::Bool(true));
@@ -178,7 +178,7 @@ impl CurlDownloader {
.as_ref()
.map(|pm| pm.get_proxy_for_request(url))
.transpose()
- .map_err(|e| anyhow::anyhow!(e.message))?
+ .map_err(|e| anyhow::anyhow!(e.get_message().to_string()))?
.and_then(|p| p.get_status(Some(" using proxy (%s)")).ok())
.unwrap_or_default();
// `attributes.redirects == 0 && attributes.retries == 0` in PHP is always true here since
@@ -206,7 +206,7 @@ impl CurlDownloader {
)?;
let send_options =
crate::util::StreamContextFactory::init_options(&current_url, send_options, true)
- .map_err(|e| anyhow::anyhow!(e.message))?;
+ .map_err(|e| anyhow::anyhow!(e.get_message().to_string()))?;
let send_result = self
.send_once(&current_url, &send_options, copy_to, &attributes)
@@ -304,26 +304,24 @@ impl CurlDownloader {
if let Some(filename) = filename {
unlink_silent(format!("{}~", filename));
}
- // PHP throws a MaxFileSizeExceededException (a TransportException subclass) with
- // the raw "Maximum allowed download size reached..." message verbatim rather than
- // wrapping it in the generic curl-error text.
+ // The message carries the raw "Maximum allowed download size reached..." text
+ // rather than the generic curl-error wrapper used below.
if transport_err.is_max_file_size {
return Ok(Decision::Failed(
- MaxFileSizeExceededException(TransportException::new(
- transport_err.message,
- 0,
- ))
- .0,
+ MaxFileSizeExceededException::new(transport_err.message).into(),
));
}
- return Ok(Decision::Failed(TransportException::new(
- format!(
- "curl error while downloading {}: {}",
- Url::sanitize(url.to_string()),
- transport_err.message
- ),
- 0,
- )));
+ return Ok(Decision::Failed(
+ TransportException::new(
+ format!(
+ "curl error while downloading {}: {}",
+ Url::sanitize(url.to_string()),
+ transport_err.message
+ ),
+ 0,
+ )
+ .into(),
+ ));
}
};
@@ -373,7 +371,7 @@ impl CurlDownloader {
});
}
Ok(_) => {}
- Err(e) => return Ok(Decision::Failed(e)),
+ Err(e) => return Ok(Decision::Failed((*e).into())),
}
// Handle 3xx redirects, 304 Not Modified excluded.
@@ -401,7 +399,7 @@ impl CurlDownloader {
if let Some(filename) = filename {
unlink_silent(format!("{}~", filename));
}
- return Ok(Decision::Failed(e));
+ return Ok(Decision::Failed((*e).into()));
}
}
}
@@ -443,7 +441,7 @@ impl CurlDownloader {
e.set_headers(curl_response.inner.get_headers().clone());
e.set_status_code(Some(curl_response.inner.get_status_code()));
e.set_response(curl_response.inner.get_body().map(|s| s.to_string()));
- return Ok(Decision::Failed(e));
+ return Ok(Decision::Failed((*e).into()));
}
// storeAuth on success.
@@ -625,7 +623,7 @@ impl CurlDownloader {
url: &str,
attributes: &IndexMap<String, PhpMixed>,
response: &CurlResponse,
- ) -> anyhow::Result<Result<String, TransportException>> {
+ ) -> anyhow::Result<Result<String, Box<TransportException>>> {
let mut target_url = String::new();
if let Some(location_header) = response.inner.get_header("location")
&& !location_header.is_empty()
@@ -682,14 +680,14 @@ impl CurlDownloader {
return Ok(Ok(target_url));
}
- Ok(Err(TransportException::new(
+ Ok(Err(Box::new(TransportException::new(
format!(
"The \"{}\" file could not be downloaded, got redirect without Location ({})",
url,
response.inner.get_status_message().unwrap_or_default()
),
0,
- )))
+ ))))
}
fn is_authenticated_retry_needed(
@@ -699,7 +697,7 @@ impl CurlDownloader {
filename: Option<&str>,
attributes: &IndexMap<String, PhpMixed>,
response: &CurlResponse,
- ) -> anyhow::Result<Result<PromptAuthResult, TransportException>> {
+ ) -> anyhow::Result<Result<PromptAuthResult, Box<TransportException>>> {
let retry_auth_failure = attributes
.get("retryAuthFailure")
.and_then(|b| b.as_bool())
@@ -808,7 +806,7 @@ impl CurlDownloader {
filename: Option<&str>,
response: &CurlResponse,
error_message: &str,
- ) -> TransportException {
+ ) -> Box<TransportException> {
if let Some(filename) = filename {
unlink_silent(format!("{}~", filename));
}
@@ -836,13 +834,13 @@ impl CurlDownloader {
);
}
- TransportException::new(
+ Box::new(TransportException::new(
format!(
"The \"{}\" file could not be downloaded ({}){}",
url, error_message, details
),
response.inner.get_status_code(),
- )
+ ))
}
fn method_is_get(options: &IndexMap<String, PhpMixed>) -> bool {
diff --git a/crates/shirabe/src/util/http/proxy_item.rs b/crates/shirabe/src/util/http/proxy_item.rs
index 1a0b3ee8..73948f88 100644
--- a/crates/shirabe/src/util/http/proxy_item.rs
+++ b/crates/shirabe/src/util/http/proxy_item.rs
@@ -20,28 +20,22 @@ impl ProxyItem {
let syntax_error = format!("unsupported `{}` syntax", env_name);
if strpbrk(&proxy_url, "\r\n\t").is_some() {
- return Err(RuntimeException {
- message: syntax_error,
- code: 0,
- });
+ return Err(RuntimeException::new(syntax_error));
}
let proxy_parsed = parse_url_all(&proxy_url);
let proxy = match proxy_parsed.as_array() {
None => {
- return Err(RuntimeException {
- message: syntax_error,
- code: 0,
- });
+ return Err(RuntimeException::new(syntax_error));
}
Some(a) => a.clone(),
};
if !proxy.contains_key("host") {
- return Err(RuntimeException {
- message: format!("unable to find proxy host in {}", env_name),
- code: 0,
- });
+ return Err(RuntimeException::new(format!(
+ "unable to find proxy host in {}",
+ env_name
+ )));
}
let scheme = if proxy.contains_key("scheme") {
@@ -100,16 +94,16 @@ impl ProxyItem {
// but is considered valid depending on the PHP or Curl version.
let port = match port {
None => {
- return Err(RuntimeException {
- message: format!("unable to find proxy port in {}", env_name),
- code: 0,
- });
+ return Err(RuntimeException::new(format!(
+ "unable to find proxy port in {}",
+ env_name
+ )));
}
Some(0) => {
- return Err(RuntimeException {
- message: format!("port 0 is reserved in {}", env_name),
- code: 0,
- });
+ return Err(RuntimeException::new(format!(
+ "port 0 is reserved in {}",
+ env_name
+ )));
}
Some(p) => p,
};
diff --git a/crates/shirabe/src/util/http/proxy_manager.rs b/crates/shirabe/src/util/http/proxy_manager.rs
index 82e8ebc5..13f0b521 100644
--- a/crates/shirabe/src/util/http/proxy_manager.rs
+++ b/crates/shirabe/src/util/http/proxy_manager.rs
@@ -71,12 +71,12 @@ impl ProxyManager {
pub fn get_proxy_for_request(
&self,
request_url: &str,
- ) -> Result<RequestProxy, TransportException> {
+ ) -> Result<RequestProxy, Box<TransportException>> {
if let Some(ref error) = self.error {
- return Err(TransportException::new(
+ return Err(Box::new(TransportException::new(
format!("Unable to use a proxy: {}", error),
0,
- ));
+ )));
}
let scheme = request_url.split("://").next().unwrap_or("").to_string();
diff --git a/crates/shirabe/src/util/http/request_proxy.rs b/crates/shirabe/src/util/http/request_proxy.rs
index 1262622f..78a64078 100644
--- a/crates/shirabe/src/util/http/request_proxy.rs
+++ b/crates/shirabe/src/util/http/request_proxy.rs
@@ -48,7 +48,7 @@ impl RequestProxy {
pub fn get_curl_options(
&self,
ssl_options: &IndexMap<String, PhpMixed>,
- ) -> Result<IndexMap<i64, PhpMixed>, TransportException> {
+ ) -> Result<IndexMap<i64, PhpMixed>, Box<TransportException>> {
// PHP guards an HTTPS proxy behind `is_secure() && !supports_secure_proxy()` because
// libcurl < 7.52.0 cannot speak TLS to a proxy. Shirabe always can (see
// supports_secure_proxy), so the guard is dropped.
@@ -90,10 +90,9 @@ impl RequestProxy {
return Ok(format.replace("%s", self.status.as_deref().unwrap()));
}
- Err(InvalidArgumentException {
- message: "String format specifier is missing".to_string(),
- code: 0,
- })
+ Err(InvalidArgumentException::new(
+ "String format specifier is missing".to_string(),
+ ))
}
pub fn is_excluded_by_no_proxy(&self) -> bool {
diff --git a/crates/shirabe/src/util/http_downloader.rs b/crates/shirabe/src/util/http_downloader.rs
index b60664da..e53ad82f 100644
--- a/crates/shirabe/src/util/http_downloader.rs
+++ b/crates/shirabe/src/util/http_downloader.rs
@@ -17,6 +17,7 @@ use crate::util::http::Response;
use crate::util::sync_executor;
use indexmap::IndexMap;
use shirabe_external_packages::composer::pcre::{CaptureKey, Preg};
+use shirabe_php_shim::Catch as _;
use shirabe_php_shim::{
InvalidArgumentException, LogicException, PhpMixed, array_replace_recursive, extension_loaded,
file_get_contents, function_exists, implode, is_numeric, php_regex, rawurldecode,
@@ -205,19 +206,14 @@ impl HttpDownloader {
return self.mock_get(url, &options);
}
if url.is_empty() {
- return Err(InvalidArgumentException {
- message: "$url must not be an empty string".to_string(),
- code: 0,
- }
+ return Err(InvalidArgumentException::new(
+ "$url must not be an empty string".to_string(),
+ )
.into());
}
if !sync && !self.allow_async {
- return Err(LogicException {
- message:
- "You must use the HttpDownloader instance which is part of a Composer\\Loop instance to be able to run async http requests"
- .to_string(),
- code: 0,
- }
+ return Err(LogicException::new("You must use the HttpDownloader instance which is part of a Composer\\Loop instance to be able to run async http requests"
+ .to_string())
.into());
}
@@ -321,7 +317,7 @@ impl HttpDownloader {
let curl = self.curl.as_ref().unwrap();
return match curl.download(&origin, url, options, copy_to).await {
Ok(Ok(response)) => Ok(response),
- Ok(Err(transport_exception)) => Err(transport_exception.into()),
+ Ok(Err(e)) => Err(e),
Err(e) => Err(e),
};
}
@@ -463,7 +459,7 @@ impl HttpDownloader {
/// @internal
pub fn get_exception_hints(e: &anyhow::Error) -> Option<Vec<String>> {
- let e_as_transport: Option<&TransportException> = e.downcast_ref::<TransportException>();
+ let e_as_transport: Option<&TransportException> = e.catch::<TransportException>();
e_as_transport?;
let e_as_transport = e_as_transport.unwrap();
@@ -600,11 +596,7 @@ impl HttpDownloader {
options: &IndexMap<String, PhpMixed>,
) -> anyhow::Result<Response> {
if file_url.is_empty() {
- return Err(LogicException {
- message: "url cannot be an empty string".to_string(),
- code: 0,
- }
- .into());
+ return Err(LogicException::new("url cannot be an empty string".to_string()).into());
}
let mock = self
diff --git a/crates/shirabe/src/util/no_proxy_pattern.rs b/crates/shirabe/src/util/no_proxy_pattern.rs
index 582fdb68..83adb09f 100644
--- a/crates/shirabe/src/util/no_proxy_pattern.rs
+++ b/crates/shirabe/src/util/no_proxy_pattern.rs
@@ -153,27 +153,24 @@ impl NoProxyPattern {
let mask = network.netmask.as_deref().unwrap_or_default();
let ip = target.ip.as_slice();
if net.is_empty() {
- return Err(RuntimeException {
- message: format!(
- "Could not parse network IP {}",
- String::from_utf8_lossy(net)
- ),
- code: 0,
- }
+ return Err(RuntimeException::new(format!(
+ "Could not parse network IP {}",
+ String::from_utf8_lossy(net)
+ ))
.into());
}
if mask.is_empty() {
- return Err(RuntimeException {
- message: format!("Could not parse netmask {}", String::from_utf8_lossy(mask)),
- code: 0,
- }
+ return Err(RuntimeException::new(format!(
+ "Could not parse netmask {}",
+ String::from_utf8_lossy(mask)
+ ))
.into());
}
if ip.is_empty() {
- return Err(RuntimeException {
- message: format!("Could not parse target IP {}", String::from_utf8_lossy(ip)),
- code: 0,
- }
+ return Err(RuntimeException::new(format!(
+ "Could not parse target IP {}",
+ String::from_utf8_lossy(ip)
+ ))
.into());
}
@@ -327,23 +324,17 @@ impl NoProxyPattern {
// Get the network from the address and mask
if netmask.is_empty() {
- return Err(RuntimeException {
- message: format!(
- "Could not parse netmask {}",
- String::from_utf8_lossy(&netmask)
- ),
- code: 0,
- }
+ return Err(RuntimeException::new(format!(
+ "Could not parse netmask {}",
+ String::from_utf8_lossy(&netmask)
+ ))
.into());
}
if range_ip.is_empty() {
- return Err(RuntimeException {
- message: format!(
- "Could not parse range IP {}",
- String::from_utf8_lossy(range_ip)
- ),
- code: 0,
- }
+ return Err(RuntimeException::new(format!(
+ "Could not parse range IP {}",
+ String::from_utf8_lossy(range_ip)
+ ))
.into());
}
diff --git a/crates/shirabe/src/util/perforce.rs b/crates/shirabe/src/util/perforce.rs
index ac455fc7..d98f1edf 100644
--- a/crates/shirabe/src/util/perforce.rs
+++ b/crates/shirabe/src/util/perforce.rs
@@ -359,17 +359,13 @@ impl Perforce {
if index.is_none() {
return Ok(false);
}
- return Err(Exception {
- message: format!("p4 command not found in path: {}", error_output),
- code: 0,
- }
+ return Err(Exception::new(format!(
+ "p4 command not found in path: {}",
+ error_output
+ ))
.into());
}
- return Err(Exception {
- message: format!("Invalid user name: {}", user),
- code: 0,
- }
- .into());
+ return Err(Exception::new(format!("Invalid user name: {}", user)).into());
}
Ok(true)
@@ -497,11 +493,7 @@ impl Perforce {
let spec = match fopen(&client_spec, "w") {
Ok(spec) => spec,
Err(e) => {
- return Err(Exception {
- message: e.to_string(),
- code: 0,
- }
- .into());
+ return Err(Exception::new(e.to_string()).into());
}
};
let result = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| {
@@ -509,11 +501,7 @@ impl Perforce {
}));
if let Err(e) = result {
fclose(&spec);
- return Err(Exception {
- message: format!("{:?}", e),
- code: 0,
- }
- .into());
+ return Err(Exception::new(format!("{:?}", e)).into());
}
fclose(&spec);
Ok(())
@@ -565,13 +553,10 @@ impl Perforce {
process.run(None, indexmap::IndexMap::new())?;
if !process.is_successful() {
- return Err(Exception {
- message: format!(
- "Error logging in:{}",
- self.process.borrow().get_error_output()
- ),
- code: 0,
- }
+ return Err(Exception::new(format!(
+ "Error logging in:{}",
+ self.process.borrow().get_error_output()
+ ))
.into());
}
}
diff --git a/crates/shirabe/src/util/platform.rs b/crates/shirabe/src/util/platform.rs
index a71fea92..2bb5cf99 100644
--- a/crates/shirabe/src/util/platform.rs
+++ b/crates/shirabe/src/util/platform.rs
@@ -36,10 +36,9 @@ impl Platform {
return Ok(String::new());
}
- return Err(RuntimeException {
- message: "Could not determine the current working directory".to_string(),
- code: 0,
- }
+ return Err(RuntimeException::new(
+ "Could not determine the current working directory".to_string(),
+ )
.into());
}
@@ -159,11 +158,7 @@ impl Platform {
}
}
- Err(RuntimeException {
- message: "Could not determine user directory".to_string(),
- code: 0,
- }
- .into())
+ Err(RuntimeException::new("Could not determine user directory".to_string()).into())
}
/// @return bool Whether the host machine is running on the Windows Subsystem for Linux (WSL)
diff --git a/crates/shirabe/src/util/process_executor.rs b/crates/shirabe/src/util/process_executor.rs
index 463c5d19..b9373b6f 100644
--- a/crates/shirabe/src/util/process_executor.rs
+++ b/crates/shirabe/src/util/process_executor.rs
@@ -13,6 +13,7 @@ use shirabe_external_packages::symfony::process::Process;
use shirabe_external_packages::symfony::process::ProcessMock;
use shirabe_external_packages::symfony::process::exception::ProcessSignaledException;
use shirabe_external_packages::symfony::process::exception::RuntimeException as SymfonyProcessRuntimeException;
+use shirabe_php_shim::Catch as _;
use shirabe_php_shim::{
LogicException, PHP_EOL, PhpMixed, RuntimeException, array_intersect, array_map,
escapeshellarg, explode, implode, in_array_strict, is_array, is_dir, is_numeric, is_string,
@@ -253,17 +254,13 @@ impl ProcessExecutor {
Some(Self::get_timeout() as f64),
)?;
} else {
- return Err(LogicException {
- message: "Invalid command type".to_string(),
- code: 0,
- }
- .into());
+ return Err(LogicException::new("Invalid command type".to_string()).into());
}
if !Platform::is_windows() && tty {
// PHP: try { $process->setTty(true); } catch (RuntimeException $e) { /* ignore */ }
if let Err(e) = process.set_tty(true)
- && e.downcast_ref::<SymfonyProcessRuntimeException>().is_none()
+ && !e.is_instanceof::<SymfonyProcessRuntimeException>()
{
return Err(e);
}
@@ -312,7 +309,7 @@ impl ProcessExecutor {
let final_result: anyhow::Result<()> = match result {
Ok(()) => Ok(()),
Err(e) => {
- if let Some(pse) = e.downcast_ref::<ProcessSignaledException>() {
+ if let Some(pse) = e.catch::<ProcessSignaledException>() {
if signal_handler.is_triggered() {
// exiting as we were signaled and the child process exited too due to the signal
signal_handler.exit_with_last_signal();
@@ -451,21 +448,18 @@ impl ProcessExecutor {
// strict-mode mismatch) extends `\RuntimeException`, so PHP call sites that
// `catch (\RuntimeException $e)` around a mock-driven git/hg/svn call (e.g.
// `GitDriver::supports`) treat a mismatch as an ordinary recoverable failure. Using
- // the same `RuntimeException` type here keeps `downcast_ref::<RuntimeException>()`
- // checks working the same way against a mismatch.
- return Err(RuntimeException {
- message: format!(
- "Received unexpected command {:?} in \"{}\"{}{}{}Received calls:{}{}",
- command,
- cwd.unwrap_or(""),
- PHP_EOL,
- expected,
- PHP_EOL,
- PHP_EOL,
- received
- ),
- code: 0,
- }
+ // the same `RuntimeException` type here keeps `catch::<RuntimeException>()` checks
+ // working the same way against a mismatch.
+ return Err(RuntimeException::new(format!(
+ "Received unexpected command {:?} in \"{}\"{}{}{}Received calls:{}{}",
+ command,
+ cwd.unwrap_or(""),
+ PHP_EOL,
+ expected,
+ PHP_EOL,
+ PHP_EOL,
+ received
+ ))
.into());
}
@@ -645,10 +639,7 @@ impl ProcessExecutor {
Box::pin(async move {
if !allow_async {
- return Err(LogicException {
- message: "You must use the ProcessExecutor instance which is part of a Composer\\Loop instance to be able to run async processes".to_string(),
- code: 0,
- }
+ return Err(LogicException::new("You must use the ProcessExecutor instance which is part of a Composer\\Loop instance to be able to run async processes".to_string())
.into());
}
@@ -682,11 +673,7 @@ impl ProcessExecutor {
Some(Self::get_timeout() as f64),
)?
} else {
- return Err(LogicException {
- message: "Invalid command type".to_string(),
- code: 0,
- }
- .into());
+ return Err(LogicException::new("Invalid command type".to_string()).into());
};
process.start(None, IndexMap::new())?;
diff --git a/crates/shirabe/src/util/remote_filesystem.rs b/crates/shirabe/src/util/remote_filesystem.rs
index 2dafc0d3..e2901b2c 100644
--- a/crates/shirabe/src/util/remote_filesystem.rs
+++ b/crates/shirabe/src/util/remote_filesystem.rs
@@ -14,6 +14,7 @@ use crate::util::http::ProxyManager;
use crate::util::http::Response;
use indexmap::IndexMap;
use shirabe_external_packages::composer::pcre::{CaptureKey, Preg};
+use shirabe_php_shim::Catch as _;
use shirabe_php_shim::{
PHP_URL_HOST, PHP_URL_PATH, PHP_URL_SCHEME, PHP_VERSION_ID, PhpMixed, RuntimeException,
STREAM_NOTIFY_FAILURE, STREAM_NOTIFY_FILE_SIZE_IS, STREAM_NOTIFY_PROGRESS,
@@ -216,12 +217,11 @@ impl RemoteFilesystem {
let mut file_url = file_url.to_string();
if options.contains_key("prevent_ip_access_callable") {
- return Err(anyhow::anyhow!(RuntimeException {
- message:
- "RemoteFilesystem doesn't support the 'prevent_ip_access_callable' config."
- .to_string(),
- code: 0,
- }));
+ return Err(RuntimeException::new(
+ "RemoteFilesystem doesn't support the 'prevent_ip_access_callable' config."
+ .to_string(),
+ )
+ .into());
}
if let Some(token) = options.get("gitlab-token").cloned() {
@@ -404,7 +404,7 @@ impl RemoteFilesystem {
})();
let mut caught_e: Option<anyhow::Error> = None;
if let Err(mut e) = inner_result {
- if let Some(te) = e.downcast_mut::<TransportException>() {
+ if let Some(te) = e.catch_mut::<TransportException>() {
if !http_response_header.is_empty() && !http_response_header[0].is_empty() {
te.set_headers(http_response_header.clone());
te.set_status_code(Self::find_status_code(&http_response_header));
@@ -535,7 +535,7 @@ impl RemoteFilesystem {
);
}
- let mut e = TransportException::new_with_code(
+ let mut e = TransportException::new(
format!(
"The \"{}\" file could not be downloaded ({})",
self.file_url, http_response_header[0]
@@ -607,13 +607,14 @@ impl RemoteFilesystem {
if result.is_some() && file_name.is_some() && !is_redirect {
let result_str = result.as_deref().unwrap();
if result_str.is_empty() {
- return Err(anyhow::anyhow!(TransportException::new(
+ return Err(TransportException::new(
format!(
"\"{}\" appears broken, and returned an empty 200 response",
self.file_url
),
0,
- )));
+ )
+ .into());
}
// TODO(phase-c): PHP captures the file_put_contents warning here via set_error_handler
@@ -623,7 +624,7 @@ impl RemoteFilesystem {
let write_result =
file_put_contents(file_name.as_deref().unwrap(), result_str.as_bytes());
if write_result.is_none() {
- return Err(anyhow::anyhow!(TransportException::new(
+ return Err(TransportException::new(
format!(
"The \"{}\" file could not be written to {}: {}",
self.file_url,
@@ -631,7 +632,8 @@ impl RemoteFilesystem {
put_error_message
),
0,
- )));
+ )
+ .into());
}
let _ = put_error_message;
}
@@ -659,7 +661,7 @@ impl RemoteFilesystem {
}
if result.is_none() {
- let mut e = TransportException::new_with_code(
+ let mut e = TransportException::new(
format!(
"The \"{}\" file could not be downloaded: {}",
self.file_url, error_message
@@ -750,11 +752,12 @@ impl RemoteFilesystem {
&& let Some(max) = max_file_size
&& Platform::strlen(r) >= max
{
- return Err(anyhow::anyhow!(MaxFileSizeExceededException::new(format!(
+ return Err(MaxFileSizeExceededException::new(format!(
"Maximum allowed download size reached. Downloaded {} of allowed {} bytes",
Platform::strlen(r),
max
- ))));
+ ))
+ .into());
}
if PHP_VERSION_ID >= 80400 {
@@ -785,14 +788,15 @@ impl RemoteFilesystem {
match notification_code {
x if x == STREAM_NOTIFY_FAILURE => {
if 400 == message_code {
- return Err(anyhow::anyhow!(TransportException::new_with_code(
+ return Err(TransportException::new(
format!(
"The '{}' URL could not be accessed: {}",
self.file_url,
message.unwrap_or_default()
),
message_code,
- )));
+ )
+ .into());
}
}
x if x == STREAM_NOTIFY_FILE_SIZE_IS => {
@@ -848,10 +852,7 @@ impl RemoteFilesystem {
self.retry = result.retry;
if self.retry {
- return Err(anyhow::anyhow!(TransportException::new(
- "RETRY".to_string(),
- 0,
- )));
+ return Err(TransportException::new("RETRY".to_string(), 0).into());
}
Ok(())
}
@@ -1043,10 +1044,11 @@ impl RemoteFilesystem {
// RemoteFilesystem as a String; from_utf8_lossy can corrupt binary payloads
Some(d) => Some(String::from_utf8_lossy(&d).into_owned()),
None => {
- return Err(anyhow::anyhow!(TransportException::new(
+ return Err(TransportException::new(
"Failed to decode zlib stream".to_string(),
0,
- )));
+ )
+ .into());
}
};
}
diff --git a/crates/shirabe/src/util/stream_context_factory.rs b/crates/shirabe/src/util/stream_context_factory.rs
index cae00c08..b407e897 100644
--- a/crates/shirabe/src/util/stream_context_factory.rs
+++ b/crates/shirabe/src/util/stream_context_factory.rs
@@ -22,7 +22,7 @@ impl StreamContextFactory {
url: &str,
default_options: IndexMap<String, PhpMixed>,
default_params: IndexMap<String, PhpMixed>,
- ) -> anyhow::Result<PhpMixed, TransportException> {
+ ) -> anyhow::Result<PhpMixed, Box<TransportException>> {
let mut options: IndexMap<String, PhpMixed> = {
let mut http = IndexMap::new();
// specify defaults again to try and work better with curlwrappers enabled
@@ -66,7 +66,7 @@ impl StreamContextFactory {
url: &str,
mut options: IndexMap<String, PhpMixed>,
for_curl: bool,
- ) -> anyhow::Result<IndexMap<String, PhpMixed>, TransportException> {
+ ) -> anyhow::Result<IndexMap<String, PhpMixed>, Box<TransportException>> {
// Make sure the headers are in an array form
let has_header = options
.get("http")
@@ -105,23 +105,23 @@ impl StreamContextFactory {
if proxy.is_secure() {
if !extension_loaded("openssl") {
- return Err(TransportException::new(
+ return Err(Box::new(TransportException::new(
"You must enable the openssl extension to use a secure proxy."
.to_string(),
0,
- ));
+ )));
}
if is_https_request {
- return Err(TransportException::new(
+ return Err(Box::new(TransportException::new(
"You must enable the curl extension to make https requests through a secure proxy.".to_string(),
0,
- ));
+ )));
}
} else if is_https_request && !extension_loaded("openssl") {
- return Err(TransportException::new(
+ return Err(Box::new(TransportException::new(
"You must enable the openssl extension to make https requests through a proxy.".to_string(),
0,
- ));
+ )));
}
// Header will be a Proxy-Authorization string or not set
@@ -224,7 +224,7 @@ impl StreamContextFactory {
// `logger` was a PSR LoggerInterface; CaBundle is slated for removal so
// it is now an unused `()` placeholder.
logger: (),
- ) -> anyhow::Result<IndexMap<String, PhpMixed>, TransportException> {
+ ) -> anyhow::Result<IndexMap<String, PhpMixed>, Box<TransportException>> {
let ciphers = [
"ECDHE-RSA-AES128-GCM-SHA256",
"ECDHE-ECDSA-AES128-GCM-SHA256",
@@ -336,10 +336,10 @@ impl StreamContextFactory {
if let Some(ref cafile) = cafile
&& (!Filesystem::is_readable(cafile) || !CaBundle::validate_ca_file(cafile, logger))
{
- return Err(TransportException::new(
+ return Err(Box::new(TransportException::new(
"The configured cafile was not valid or could not be read.".to_string(),
0,
- ));
+ )));
}
let capath = defaults
@@ -351,10 +351,10 @@ impl StreamContextFactory {
if let Some(ref capath) = capath
&& (!shirabe_php_shim::is_dir(capath) || !Filesystem::is_readable(capath))
{
- return Err(TransportException::new(
+ return Err(Box::new(TransportException::new(
"The configured capath was not valid or could not be read.".to_string(),
0,
- ));
+ )));
}
// Disable TLS compression to prevent CRIME attacks where supported.
diff --git a/crates/shirabe/src/util/svn.rs b/crates/shirabe/src/util/svn.rs
index a2974760..aaa0c6d1 100644
--- a/crates/shirabe/src/util/svn.rs
+++ b/crates/shirabe/src/util/svn.rs
@@ -177,11 +177,7 @@ impl Svn {
&& stripos(&full_output, "svn: E170001:").is_none()
&& stripos(&full_output, "svn: E215004:").is_none()
{
- return Err(RuntimeException {
- message: full_output,
- code: 0,
- }
- .into());
+ return Err(RuntimeException::new(full_output).into());
}
if !self.has_auth() {
@@ -196,11 +192,7 @@ impl Svn {
return self.execute_with_auth_retry(svn_command, cwd, url, path, verbose);
}
- Err(RuntimeException {
- message: format!("wrong credentials provided ({})", full_output),
- code: 0,
- }
- .into())
+ Err(RuntimeException::new(format!("wrong credentials provided ({})", full_output)).into())
}
pub fn set_cache_credentials(&mut self, cache_credentials: bool) {
@@ -213,10 +205,9 @@ impl Svn {
pub(crate) fn do_auth_dance(&mut self) -> anyhow::Result<&mut Self> {
// cannot ask for credentials in non interactive mode
if !self.io.is_interactive() {
- return Err(RuntimeException {
- message: "can not ask for authentication in non interactive mode".to_string(),
- code: 0,
- }
+ return Err(RuntimeException::new(
+ "can not ask for authentication in non interactive mode".to_string(),
+ )
.into());
}
@@ -310,11 +301,7 @@ impl Svn {
/// @throws \LogicException
pub(crate) fn get_password(&self) -> anyhow::Result<String> {
if self.credentials.is_none() {
- return Err(LogicException {
- message: "No svn auth detected.".to_string(),
- code: 0,
- }
- .into());
+ return Err(LogicException::new("No svn auth detected.".to_string()).into());
}
Ok(self.credentials.as_ref().unwrap().password.clone())
@@ -325,11 +312,7 @@ impl Svn {
/// @throws \LogicException
pub(crate) fn get_username(&self) -> anyhow::Result<String> {
if self.credentials.is_none() {
- return Err(LogicException {
- message: "No svn auth detected.".to_string(),
- code: 0,
- }
- .into());
+ return Err(LogicException::new("No svn auth detected.".to_string()).into());
}
Ok(self.credentials.as_ref().unwrap().username.clone())
diff --git a/crates/shirabe/src/util/tar.rs b/crates/shirabe/src/util/tar.rs
index f5b0ebbe..94320edb 100644
--- a/crates/shirabe/src/util/tar.rs
+++ b/crates/shirabe/src/util/tar.rs
@@ -20,10 +20,8 @@ impl Tar {
/// UTF-8 could never survive the JSON parsing that follows in PHP either.
fn content_to_string(content: Vec<u8>) -> anyhow::Result<String> {
String::from_utf8(content).map_err(|_| {
- anyhow::anyhow!(RuntimeException {
- message: "composer.json in the archive is not valid UTF-8".to_string(),
- code: 0,
- })
+ RuntimeException::new("composer.json in the archive is not valid UTF-8".to_string())
+ .into()
})
}
@@ -38,17 +36,14 @@ impl Tar {
if folder_file.is_dir() {
top_level_paths.insert(name, true);
if top_level_paths.len() > 1 {
- return Err(anyhow::anyhow!(RuntimeException {
- message: format!(
- "Archive has more than one top level directories, and no composer.json was found on the top level, so it's an invalid archive. Top level paths found were: {}",
- top_level_paths
- .keys()
- .cloned()
- .collect::<Vec<_>>()
- .join(",")
- ),
- code: 0,
- }));
+ return Err(RuntimeException::new(format!(
+ "Archive has more than one top level directories, and no composer.json was found on the top level, so it's an invalid archive. Top level paths found were: {}",
+ top_level_paths
+ .keys()
+ .cloned()
+ .collect::<Vec<_>>()
+ .join(",")
+ )).into());
}
}
}
@@ -63,11 +58,10 @@ impl Tar {
return Self::content_to_string(file.get_content());
}
- Err(anyhow::anyhow!(RuntimeException {
- message:
- "No composer.json found either at the top level or within the topmost directory"
- .to_string(),
- code: 0,
- }))
+ Err(RuntimeException::new(
+ "No composer.json found either at the top level or within the topmost directory"
+ .to_string(),
+ )
+ .into())
}
}
diff --git a/crates/shirabe/src/util/zip.rs b/crates/shirabe/src/util/zip.rs
index a671d63b..0ba177d0 100644
--- a/crates/shirabe/src/util/zip.rs
+++ b/crates/shirabe/src/util/zip.rs
@@ -10,10 +10,9 @@ pub struct Zip;
impl Zip {
pub fn get_composer_json(path_to_zip: &str) -> anyhow::Result<Option<String>> {
if !extension_loaded("zip") {
- return Err(RuntimeException {
- message: "The Zip Util requires PHP's zip extension".to_string(),
- code: 0,
- }
+ return Err(RuntimeException::new(
+ "The Zip Util requires PHP's zip extension".to_string(),
+ )
.into());
}
@@ -64,13 +63,10 @@ impl Zip {
if dir_name == "." {
top_level_paths.insert(name, true);
if top_level_paths.len() > 1 {
- return Err(RuntimeException {
- message: format!(
- "Archive has more than one top level directories, and no composer.json was found on the top level, so it's an invalid archive. Top level paths found were: {}",
- implode(",", &top_level_paths.keys().cloned().collect::<Vec<_>>())
- ),
- code: 0,
- }
+ return Err(RuntimeException::new(format!(
+ "Archive has more than one top level directories, and no composer.json was found on the top level, so it's an invalid archive. Top level paths found were: {}",
+ implode(",", &top_level_paths.keys().cloned().collect::<Vec<_>>())
+ ))
.into());
}
continue;
@@ -80,13 +76,10 @@ impl Zip {
if !dir_name.contains('\\') && !dir_name.contains('/') {
top_level_paths.insert(format!("{}/", dir_name), true);
if top_level_paths.len() > 1 {
- return Err(RuntimeException {
- message: format!(
- "Archive has more than one top level directories, and no composer.json was found on the top level, so it's an invalid archive. Top level paths found were: {}",
- implode(",", &top_level_paths.keys().cloned().collect::<Vec<_>>())
- ),
- code: 0,
- }
+ return Err(RuntimeException::new(format!(
+ "Archive has more than one top level directories, and no composer.json was found on the top level, so it's an invalid archive. Top level paths found were: {}",
+ implode(",", &top_level_paths.keys().cloned().collect::<Vec<_>>())
+ ))
.into());
}
}
@@ -101,12 +94,10 @@ impl Zip {
}
}
- Err(RuntimeException {
- message:
- "No composer.json found either at the top level or within the topmost directory"
- .to_string(),
- code: 0,
- }
+ Err(RuntimeException::new(
+ "No composer.json found either at the top level or within the topmost directory"
+ .to_string(),
+ )
.into())
}
}
diff --git a/crates/shirabe/tests/downloader/download_manager_test.rs b/crates/shirabe/tests/downloader/download_manager_test.rs
index 9d12bad6..dd894565 100644
--- a/crates/shirabe/tests/downloader/download_manager_test.rs
+++ b/crates/shirabe/tests/downloader/download_manager_test.rs
@@ -253,13 +253,7 @@ fn test_full_package_download_failover() {
.expect_download()
.times(1)
.withf(|_pkg, path, _prev, _output| path == "target_dir")
- .returning(|_, _, _, _| {
- Err(RuntimeException {
- message: "Foo".to_string(),
- code: 0,
- }
- .into())
- });
+ .returning(|_, _, _, _| Err(RuntimeException::new("Foo".to_string()).into()));
let mut downloader_success = downloader_mock("source");
downloader_success
diff --git a/crates/shirabe/tests/downloader/file_downloader_test.rs b/crates/shirabe/tests/downloader/file_downloader_test.rs
index 469bf473..eac4e45e 100644
--- a/crates/shirabe/tests/downloader/file_downloader_test.rs
+++ b/crates/shirabe/tests/downloader/file_downloader_test.rs
@@ -17,6 +17,7 @@ use shirabe::util::HttpDownloader;
use shirabe::util::filesystem::{Filesystem, FilesystemMock};
use shirabe::util::http_downloader::HttpDownloaderMockHandler;
use shirabe::util::r#loop::Loop;
+use shirabe_php_shim::Catch as _;
use shirabe_php_shim::{
InvalidArgumentException, PhpMixed, RuntimeException, UnexpectedValueException,
};
@@ -84,7 +85,7 @@ fn test_download_for_package_without_dist_reference() {
let e = result.expect_err("expected InvalidArgumentException");
assert!(
- e.downcast_ref::<InvalidArgumentException>().is_some(),
+ e.is_instanceof::<InvalidArgumentException>(),
"expected InvalidArgumentException, got: {e}"
);
}
@@ -107,7 +108,7 @@ fn test_download_to_existing_file() {
let e = result.expect_err("download to an existing file was expected to throw");
assert!(
- e.downcast_ref::<RuntimeException>().is_some(),
+ e.is_instanceof::<RuntimeException>(),
"expected RuntimeException, got: {e}"
);
assert!(
@@ -167,7 +168,7 @@ fn test_download_but_file_is_unsaved() {
let e = result.expect_err("download was expected to throw");
assert!(
- e.downcast_ref::<UnexpectedValueException>().is_some(),
+ e.is_instanceof::<UnexpectedValueException>(),
"expected UnexpectedValueException, got: {e}"
);
assert!(
@@ -294,7 +295,7 @@ fn test_download_file_with_invalid_checksum() {
let e = result.expect_err("download was expected to throw");
assert!(
- e.downcast_ref::<UnexpectedValueException>().is_some(),
+ e.is_instanceof::<UnexpectedValueException>(),
"expected UnexpectedValueException, got: {e}"
);
assert!(
diff --git a/crates/shirabe/tests/event_dispatcher/event_dispatcher_test.rs b/crates/shirabe/tests/event_dispatcher/event_dispatcher_test.rs
index af8a33db..817a6954 100644
--- a/crates/shirabe/tests/event_dispatcher/event_dispatcher_test.rs
+++ b/crates/shirabe/tests/event_dispatcher/event_dispatcher_test.rs
@@ -27,6 +27,7 @@ use shirabe::util::platform::Platform;
use shirabe::util::process_executor::{MockHandler, ProcessExecutor};
use shirabe_class_map_generator::class_map::ClassMap;
use shirabe_external_packages::symfony::console::output::output_interface;
+use shirabe_php_shim::Catch as _;
use shirabe_php_shim::{PHP_EOL, PhpMixed};
fn tear_down() {
@@ -286,8 +287,7 @@ fn test_dispatcher_detect_infinite_recursion() {
let result = dispatcher.dispatch(Some("root"), Some(&mut event));
let err = result.expect_err("infinite recursion must raise a RuntimeException");
assert!(
- err.downcast_ref::<shirabe_php_shim::RuntimeException>()
- .is_some(),
+ err.is_instanceof::<shirabe_php_shim::RuntimeException>(),
"expected RuntimeException, got: {err:?}"
);
}
@@ -392,8 +392,7 @@ fn test_listener_exceptions_are_caught() {
let e = result.expect_err("expected RuntimeException");
assert!(
- e.downcast_ref::<shirabe_php_shim::RuntimeException>()
- .is_some(),
+ e.is_instanceof::<shirabe_php_shim::RuntimeException>(),
"got: {e:?}"
);
}
diff --git a/crates/shirabe/tests/json/composer_schema_test.rs b/crates/shirabe/tests/json/composer_schema_test.rs
index 9cbea150..f2a5da44 100644
--- a/crates/shirabe/tests/json/composer_schema_test.rs
+++ b/crates/shirabe/tests/json/composer_schema_test.rs
@@ -9,6 +9,7 @@
//! which property) is identical to upstream.
use shirabe::json::{JsonFile, JsonValidationException};
+use shirabe_php_shim::Catch as _;
use shirabe_php_shim::json_decode;
const NAME_PATTERN: &str = r#"^[a-z0-9]([_.-]?[a-z0-9]+)*/[a-z0-9](([_.]|-{1,2})?[a-z0-9]+)*$"#;
@@ -22,7 +23,7 @@ fn check(json: &str) -> Vec<String> {
match JsonFile::validate_json_schema("test", &data, JsonFile::LAX_SCHEMA, None) {
Ok(_) => Vec::new(),
Err(e) => e
- .downcast_ref::<JsonValidationException>()
+ .catch::<JsonValidationException>()
.unwrap()
.get_errors()
.clone(),
diff --git a/crates/shirabe/tests/json/json_file_test.rs b/crates/shirabe/tests/json/json_file_test.rs
index 49ac1605..a20e7234 100644
--- a/crates/shirabe/tests/json/json_file_test.rs
+++ b/crates/shirabe/tests/json/json_file_test.rs
@@ -3,6 +3,7 @@
use indexmap::IndexMap;
use shirabe::json::{JsonEncodeOptions, JsonFile, JsonValidationException};
use shirabe_external_packages::seld::json_lint::ParsingException;
+use shirabe_php_shim::Catch as _;
use shirabe_php_shim::PhpMixed;
/// ref: JsonFileTest::expectParseException
@@ -269,14 +270,14 @@ fn test_schema_validation_error() {
let err = json
.validate_schema(JsonFile::STRICT_SCHEMA, None)
.unwrap_err();
- let e = err.downcast_ref::<JsonValidationException>().unwrap();
+ let e = err.catch::<JsonValidationException>().unwrap();
assert_eq!(expected_message, e.get_message());
assert!(e.get_errors().contains(&expected_error));
let err = json
.validate_schema(JsonFile::LAX_SCHEMA, None)
.unwrap_err();
- let e = err.downcast_ref::<JsonValidationException>().unwrap();
+ let e = err.catch::<JsonValidationException>().unwrap();
assert_eq!(expected_message, e.get_message());
assert!(e.get_errors().contains(&expected_error));
}
@@ -298,7 +299,7 @@ fn test_schema_validation_lax_additional_properties() {
let err = json
.validate_schema(JsonFile::STRICT_SCHEMA, None)
.unwrap_err();
- let e = err.downcast_ref::<JsonValidationException>().unwrap();
+ let e = err.catch::<JsonValidationException>().unwrap();
assert_eq!(
format!("\"{}\" does not match the expected JSON schema", file),
e.get_message()
@@ -327,7 +328,7 @@ fn test_schema_validation_lax_required() {
let err = json
.validate_schema(JsonFile::STRICT_SCHEMA, None)
.unwrap_err();
- let e = err.downcast_ref::<JsonValidationException>().unwrap();
+ let e = err.catch::<JsonValidationException>().unwrap();
assert_eq!(expected_message, e.get_message());
let errors = e.get_errors();
assert!(errors.contains(&"name : \"name\" is a required property".to_string()));
@@ -338,7 +339,7 @@ fn test_schema_validation_lax_required() {
let err = json
.validate_schema(JsonFile::STRICT_SCHEMA, None)
.unwrap_err();
- let e = err.downcast_ref::<JsonValidationException>().unwrap();
+ let e = err.catch::<JsonValidationException>().unwrap();
assert_eq!(expected_message, e.get_message());
assert_eq!(
&vec!["description : \"description\" is a required property".to_string()],
@@ -350,7 +351,7 @@ fn test_schema_validation_lax_required() {
let err = json
.validate_schema(JsonFile::STRICT_SCHEMA, None)
.unwrap_err();
- let e = err.downcast_ref::<JsonValidationException>().unwrap();
+ let e = err.catch::<JsonValidationException>().unwrap();
assert_eq!(expected_message, e.get_message());
assert_eq!(
&vec!["name : \"name\" is a required property".to_string()],
@@ -362,7 +363,7 @@ fn test_schema_validation_lax_required() {
let err = json
.validate_schema(JsonFile::STRICT_SCHEMA, None)
.unwrap_err();
- let e = err.downcast_ref::<JsonValidationException>().unwrap();
+ let e = err.catch::<JsonValidationException>().unwrap();
assert_eq!(expected_message, e.get_message());
let errors = e.get_errors();
assert!(errors.contains(&"name : \"name\" is a required property".to_string()));
@@ -373,7 +374,7 @@ fn test_schema_validation_lax_required() {
let err = json
.validate_schema(JsonFile::STRICT_SCHEMA, None)
.unwrap_err();
- let e = err.downcast_ref::<JsonValidationException>().unwrap();
+ let e = err.catch::<JsonValidationException>().unwrap();
assert_eq!(expected_message, e.get_message());
let errors = e.get_errors();
assert!(errors.contains(&"name : \"name\" is a required property".to_string()));
@@ -444,7 +445,7 @@ fn test_auth_schema_validation_with_custom_data_source() {
let err = JsonFile::validate_json_schema("COMPOSER_AUTH", &json, JsonFile::AUTH_SCHEMA, None)
.unwrap_err();
- let e = err.downcast_ref::<JsonValidationException>().unwrap();
+ let e = err.catch::<JsonValidationException>().unwrap();
assert_eq!(expected_message, e.get_message());
assert_eq!(&vec![expected_error], e.get_errors());
}
@@ -519,7 +520,7 @@ fn test_composer_lock_file_merge_conflict_complex() {
std::fs::read_to_string(fixture_path("composer-lock-merge-conflict-complex.txt")).unwrap();
let err = JsonFile::parse_json(Some(&data), Some("/path/to/composer.lock")).unwrap_err();
- assert!(err.downcast_ref::<ParsingException>().is_some());
+ assert!(err.is_instanceof::<ParsingException>());
}
#[test]
@@ -531,7 +532,7 @@ fn test_composer_lock_file_merge_conflict_complex_crlf() {
.unwrap();
let err = JsonFile::parse_json(Some(&data), Some("/path/to/composer.lock")).unwrap_err();
- assert!(err.downcast_ref::<ParsingException>().is_some());
+ assert!(err.is_instanceof::<ParsingException>());
}
#[test]
diff --git a/crates/shirabe/tests/package/archiver/archive_manager_test.rs b/crates/shirabe/tests/package/archiver/archive_manager_test.rs
index a7235bf9..84feb5bc 100644
--- a/crates/shirabe/tests/package/archiver/archive_manager_test.rs
+++ b/crates/shirabe/tests/package/archiver/archive_manager_test.rs
@@ -13,6 +13,7 @@ use shirabe::util::ProcessExecutor;
use shirabe::util::http_downloader::HttpDownloader;
use shirabe::util::r#loop::Loop;
use shirabe_external_packages::symfony::process::Process;
+use shirabe_php_shim::Catch as _;
use shirabe_php_shim::{
PhpMixed, file_exists, file_put_contents, realpath, sys_get_temp_dir, unlink,
};
@@ -159,10 +160,7 @@ fn test_unknown_format() {
);
let err = result.expect_err("expected RuntimeException for unknown format");
- assert!(
- err.downcast_ref::<shirabe_php_shim::RuntimeException>()
- .is_some()
- );
+ assert!(err.is_instanceof::<shirabe_php_shim::RuntimeException>());
}
// ref: ArchiveManagerTest::testArchiveTar / testArchiveCustomFileName.
diff --git a/crates/shirabe/tests/package/loader/validating_array_loader_test.rs b/crates/shirabe/tests/package/loader/validating_array_loader_test.rs
index 07f3e4a6..1b1ed448 100644
--- a/crates/shirabe/tests/package/loader/validating_array_loader_test.rs
+++ b/crates/shirabe/tests/package/loader/validating_array_loader_test.rs
@@ -4,6 +4,7 @@ use crate::test_case;
use indexmap::IndexMap;
use shirabe::package::handle::PackageInterfaceHandle;
use shirabe::package::loader::{InvalidPackageException, LoaderInterface, ValidatingArrayLoader};
+use shirabe_php_shim::Catch as _;
use shirabe_php_shim::PhpMixed;
fn s(v: &str) -> PhpMixed {
@@ -792,7 +793,7 @@ fn test_load_failure_throws_exception() {
Ok(_) => panic!("Expected exception to be thrown"),
Err(e) => {
let exception = e
- .downcast_ref::<InvalidPackageException>()
+ .catch::<InvalidPackageException>()
.expect("Expected InvalidPackageException");
let mut errors: Vec<String> = exception.get_errors().to_vec();
expected_errors.sort();
diff --git a/crates/shirabe/tests/package/locker_test.rs b/crates/shirabe/tests/package/locker_test.rs
index f1747166..4732d679 100644
--- a/crates/shirabe/tests/package/locker_test.rs
+++ b/crates/shirabe/tests/package/locker_test.rs
@@ -10,6 +10,7 @@ use shirabe::package::handle::{CompletePackageHandle, PackageInterfaceHandle};
use shirabe::plugin::plugin_interface;
use shirabe::repository::{FindPackageConstraint, RepositoryInterfaceHandle};
use shirabe::util::process_executor::ProcessExecutor;
+use shirabe_php_shim::Catch as _;
use shirabe_php_shim::{LogicException, PhpMixed, hash};
use tempfile::TempDir;
@@ -83,7 +84,7 @@ fn test_get_not_locked_packages() {
.get_locked_repository(false)
.expect_err("getLockedRepository should fail when no lock file exists");
assert!(
- err.downcast_ref::<LogicException>().is_some(),
+ err.is_instanceof::<LogicException>(),
"expected LogicException, got: {err}"
);
}
@@ -219,7 +220,7 @@ fn test_lock_bad_packages() {
)
.expect_err("setLockData should fail for a package with no version");
assert!(
- err.downcast_ref::<LogicException>().is_some(),
+ err.is_instanceof::<LogicException>(),
"expected LogicException, got: {err}"
);
}
diff --git a/crates/shirabe/tests/plugin/plugin_installer_test.rs b/crates/shirabe/tests/plugin/plugin_installer_test.rs
index 06cd2ce9..0c82a11a 100644
--- a/crates/shirabe/tests/plugin/plugin_installer_test.rs
+++ b/crates/shirabe/tests/plugin/plugin_installer_test.rs
@@ -31,6 +31,7 @@ use shirabe::util::r#loop::Loop;
use shirabe::util::process_executor::ProcessExecutor;
use shirabe_external_packages::symfony::console::output::output_interface::VERBOSITY_NORMAL;
use shirabe_external_packages::symfony::process::PhpExecutableFinder;
+use shirabe_php_shim::Catch as _;
use shirabe_php_shim::PhpMixed;
use shirabe_semver::VersionParser;
use tempfile::TempDir;
@@ -859,8 +860,7 @@ fn test_querying_with_invalid_capability_class_name_throws() {
),
};
assert!(
- err.downcast_ref::<shirabe_php_shim::UnexpectedValueException>()
- .is_some(),
+ err.is_instanceof::<shirabe_php_shim::UnexpectedValueException>(),
"expected UnexpectedValueException for {invalid_implementation_class_name:?}, got: {err}"
);
// PHP: ->expects($this->once())->method('getCapabilities').
diff --git a/crates/shirabe/tests/repository/filesystem_repository_test.rs b/crates/shirabe/tests/repository/filesystem_repository_test.rs
index 3279f29e..a9ac91a0 100644
--- a/crates/shirabe/tests/repository/filesystem_repository_test.rs
+++ b/crates/shirabe/tests/repository/filesystem_repository_test.rs
@@ -13,6 +13,7 @@ use shirabe::package::{Link, PackageInterfaceHandle, RootAliasPackageHandle, Roo
use shirabe::repository::RepositoryInterface;
use shirabe::repository::filesystem_repository::FilesystemRepository;
use shirabe::util::filesystem::Filesystem;
+use shirabe_php_shim::Catch as _;
use shirabe_php_shim::PhpMixed;
use shirabe_semver::VersionParser;
@@ -50,7 +51,6 @@ fn test_repository_read() {
assert_eq!(packages[0].get_type(), "vendor");
}
-#[ignore = "InvalidRepositoryException message building calls shirabe_php_shim::var::get_class_err(), which is still todo!()"]
#[test]
fn test_corrupted_repository_file() {
// PHP mocks read() to return the scalar string 'foo'; a real file containing the JSON string
@@ -63,7 +63,7 @@ fn test_corrupted_repository_file() {
let result = repository.get_packages();
let err = result.unwrap_err();
assert!(
- err.is::<shirabe::repository::InvalidRepositoryException>(),
+ err.is_instanceof::<shirabe::repository::InvalidRepositoryException>(),
"expected InvalidRepositoryException, got: {err}"
);
}
diff --git a/crates/shirabe/tests/repository/vcs/git_bitbucket_driver_test.rs b/crates/shirabe/tests/repository/vcs/git_bitbucket_driver_test.rs
index 4d84bcf2..67e9c8a9 100644
--- a/crates/shirabe/tests/repository/vcs/git_bitbucket_driver_test.rs
+++ b/crates/shirabe/tests/repository/vcs/git_bitbucket_driver_test.rs
@@ -10,6 +10,7 @@ use shirabe::repository::vcs::GitBitbucketDriver;
use shirabe::util::filesystem::Filesystem;
use shirabe::util::http_downloader::{HttpDownloader, HttpDownloaderMockHandler};
use shirabe::util::process_executor::ProcessExecutor;
+use shirabe_php_shim::Catch as _;
use shirabe_php_shim::{InvalidArgumentException, PhpMixed, RuntimeException};
use tempfile::TempDir;
@@ -112,11 +113,11 @@ fn test_get_root_identifier_wrong_scm_type() {
let err = driver.get_root_identifier().unwrap_err();
let runtime = err
- .downcast_ref::<RuntimeException>()
+ .catch::<RuntimeException>()
.expect("expected RuntimeException");
assert_eq!(
"https://bitbucket.org/user/repo.git does not appear to be a git repository, use https://bitbucket.org/user/repo but remember that Bitbucket no longer supports the mercurial repositories. https://bitbucket.org/blog/sunsetting-mercurial-support-in-bitbucket",
- runtime.message
+ runtime.get_message()
);
}
@@ -250,7 +251,7 @@ fn test_initialize_invalid_repository_url() {
let result = get_driver("https://bitbucket.org/acme", io, config, http_downloader);
let err = result.unwrap_err();
assert!(
- err.downcast_ref::<InvalidArgumentException>().is_some(),
+ err.is_instanceof::<InvalidArgumentException>(),
"expected InvalidArgumentException, got: {err:?}"
);
}
diff --git a/crates/shirabe/tests/repository/vcs/git_driver_test.rs b/crates/shirabe/tests/repository/vcs/git_driver_test.rs
index 7a85d4cc..8494c1ca 100644
--- a/crates/shirabe/tests/repository/vcs/git_driver_test.rs
+++ b/crates/shirabe/tests/repository/vcs/git_driver_test.rs
@@ -12,6 +12,7 @@ use shirabe::util::filesystem::Filesystem;
use shirabe::util::http_downloader::HttpDownloaderMockHandler;
use shirabe::util::platform::Platform;
use shirabe::util::process_executor::MockHandler;
+use shirabe_php_shim::Catch as _;
use shirabe_php_shim::{PhpMixed, RuntimeException};
use tempfile::TempDir;
@@ -293,7 +294,7 @@ fn test_file_get_content_invalid_identifier() {
assert_eq!(None, driver.get_file_content("file.txt", "h").unwrap());
let err = driver.get_file_content("file.txt", "-h").unwrap_err();
- assert!(err.downcast_ref::<RuntimeException>().is_some());
+ assert!(err.is_instanceof::<RuntimeException>());
}
#[test]
@@ -324,5 +325,5 @@ fn test_get_change_date_invalid_identifier() {
let mut driver = GitDriver::new(repo_config, io, config, http_downloader, process);
let err = driver.get_change_date("-n1 --format=%at HEAD").unwrap_err();
- assert!(err.downcast_ref::<RuntimeException>().is_some());
+ assert!(err.is_instanceof::<RuntimeException>());
}
diff --git a/crates/shirabe/tests/repository/vcs/hg_driver_test.rs b/crates/shirabe/tests/repository/vcs/hg_driver_test.rs
index be36f412..4245e140 100644
--- a/crates/shirabe/tests/repository/vcs/hg_driver_test.rs
+++ b/crates/shirabe/tests/repository/vcs/hg_driver_test.rs
@@ -11,6 +11,7 @@ use shirabe::repository::vcs::HgDriver;
use shirabe::util::filesystem::Filesystem;
use shirabe::util::http_downloader::HttpDownloaderMockHandler;
use shirabe::util::process_executor::MockHandler;
+use shirabe_php_shim::Catch as _;
use shirabe_php_shim::{PhpMixed, RuntimeException};
use tempfile::TempDir;
@@ -141,7 +142,7 @@ fn test_file_get_content_invalid_identifier() {
assert_eq!(None, driver.get_file_content("file.txt", "h").unwrap());
let err = driver.get_file_content("file.txt", "-h").unwrap_err();
- assert!(err.downcast_ref::<RuntimeException>().is_some());
+ assert!(err.is_instanceof::<RuntimeException>());
}
#[test]
@@ -168,5 +169,5 @@ fn test_get_change_date_invalid_identifier() {
let driver = HgDriver::new(repo_config, io, config, http_downloader, process);
let err = driver.get_change_date("-r foo").unwrap_err();
- assert!(err.downcast_ref::<RuntimeException>().is_some());
+ assert!(err.is_instanceof::<RuntimeException>());
}
diff --git a/crates/shirabe/tests/repository/vcs/svn_driver_test.rs b/crates/shirabe/tests/repository/vcs/svn_driver_test.rs
index 6a74063d..bc45b082 100644
--- a/crates/shirabe/tests/repository/vcs/svn_driver_test.rs
+++ b/crates/shirabe/tests/repository/vcs/svn_driver_test.rs
@@ -11,6 +11,7 @@ use shirabe::repository::vcs::SvnDriver;
use shirabe::util::filesystem::Filesystem;
use shirabe::util::http_downloader::HttpDownloaderMockHandler;
use shirabe::util::process_executor::MockHandler;
+use shirabe_php_shim::Catch as _;
use shirabe_php_shim::{PhpMixed, RuntimeException};
use tempfile::TempDir;
@@ -130,10 +131,10 @@ fn test_wrong_credentials_in_url() {
let mut svn = SvnDriver::new(repo_config, console, config, http_downloader, process);
let err = svn.initialize().unwrap_err();
let runtime = err
- .downcast_ref::<RuntimeException>()
+ .catch::<RuntimeException>()
.expect("expected RuntimeException");
assert_eq!(
"Repository https://till:secret@corp.svn.local/repo could not be processed, wrong credentials provided (svn: OPTIONS of 'https://corp.svn.local/repo': authorization failed: Could not authenticate to server: rejected Basic challenge (https://corp.svn.local/))",
- runtime.message
+ runtime.get_message()
);
}
diff --git a/crates/shirabe/tests/util/auth_helper_test.rs b/crates/shirabe/tests/util/auth_helper_test.rs
index ef5daaf7..6b376f97 100644
--- a/crates/shirabe/tests/util/auth_helper_test.rs
+++ b/crates/shirabe/tests/util/auth_helper_test.rs
@@ -7,6 +7,7 @@ use shirabe::config::ConfigSourceInterface;
use shirabe::io::IOInterface;
use shirabe::io::io_interface;
use shirabe::util::{AuthHelper, Bitbucket, StoreAuth};
+use shirabe_php_shim::Catch as _;
use shirabe_php_shim::{PhpMixed, base64_encode, json_encode};
// Mirrors AuthHelperTest::setUp: a DEBUG-verbosity IOMock plus a real Config, both
@@ -560,7 +561,7 @@ fn test_store_auth_with_prompt_invalid_answer() {
let err = auth_helper
.store_auth(origin, StoreAuth::Prompt)
.expect_err("expected a RuntimeException");
- assert!(err.downcast_ref::<RuntimeException>().is_some());
+ assert!(err.is_instanceof::<RuntimeException>());
// Mirrors PHP's `->with('Do you want to store credentials for '.$origin.' in '.
// $configSourceName.' ? [Yn] ', $this->anything(), null, 'y')` verification on askAndValidate.
@@ -639,7 +640,7 @@ fn test_prompt_auth_if_needed_git_lab_no_auth_change() {
);
let err = result.expect_err("expected a TransportException");
- assert!(err.downcast_ref::<TransportException>().is_some());
+ assert!(err.is_instanceof::<TransportException>());
assert_eq!(
vec![(
diff --git a/crates/shirabe/tests/util/git_test.rs b/crates/shirabe/tests/util/git_test.rs
index 907ec38a..dbc06137 100644
--- a/crates/shirabe/tests/util/git_test.rs
+++ b/crates/shirabe/tests/util/git_test.rs
@@ -11,6 +11,7 @@ use shirabe::util::filesystem::Filesystem;
use shirabe::util::git::Git;
use shirabe::util::http_downloader::HttpDownloaderMockHandler;
use shirabe::util::process_executor::{MockExpectation, MockHandler, ProcessExecutor};
+use shirabe_php_shim::Catch as _;
use shirabe_php_shim::{PhpMixed, RuntimeException};
// No-op ConfigSourceInterface, equivalent to PHPUnit's
@@ -195,7 +196,7 @@ fn test_run_command_private_git_hub_repository_not_initial_clone_not_interactive
);
let err = result.expect_err("expected a RuntimeException");
- assert!(err.downcast_ref::<RuntimeException>().is_some());
+ assert!(err.is_instanceof::<RuntimeException>());
}
// privateGithubWithCredentialsProvider helper.
diff --git a/crates/shirabe/tests/util/http_downloader_test.rs b/crates/shirabe/tests/util/http_downloader_test.rs
index b438dca9..f1883721 100644
--- a/crates/shirabe/tests/util/http_downloader_test.rs
+++ b/crates/shirabe/tests/util/http_downloader_test.rs
@@ -11,6 +11,7 @@ use shirabe::io::io_interface;
use shirabe::util::Platform;
use shirabe::util::http_downloader::HttpDownloader;
use shirabe_external_packages::symfony::console::output::output_interface::VERBOSITY_NORMAL;
+use shirabe_php_shim::Catch as _;
use shirabe_php_shim::{PHP_EOL, PhpMixed};
// PHP performs a live HTTP get to assert the URL's user:pass is captured via
@@ -49,7 +50,7 @@ fn test_capture_authentication_params_from_url() {
if let Err(e) = fs.get(
"https://user:pass@github.com/composer/composer/404",
IndexMap::new(),
- ) && let Some(te) = e.downcast_ref::<TransportException>()
+ ) && let Some(te) = e.catch::<TransportException>()
{
assert_ne!(200, te.get_code());
}
diff --git a/crates/shirabe/tests/util/silencer_test.rs b/crates/shirabe/tests/util/silencer_test.rs
index 000e7371..8c319400 100644
--- a/crates/shirabe/tests/util/silencer_test.rs
+++ b/crates/shirabe/tests/util/silencer_test.rs
@@ -35,11 +35,7 @@ fn test_silencer() {
fn test_silenced_exception() {
let verification = format!("{}", microtime());
let err = Silencer::call(|| -> anyhow::Result<()> {
- Err(RuntimeException {
- message: verification.clone(),
- code: 0,
- }
- .into())
+ Err(RuntimeException::new(verification.clone()).into())
})
.unwrap_err();
assert_eq!(verification, err.to_string());