@@ -0,0 +1,21 @@ | |||
Error: The package catalog database is for a later ``dds`` version | |||
################################################################## | |||
If you receive this error, it indicates that the schema version of a catalog | |||
database is newer than the schema expected by the ``dds`` process that is | |||
trying to actually make use of the catalog. ``dds`` catalog databases are not | |||
forwards-compatible and cannot be downgraded. | |||
If you generated/modified the catalog using a ``dds`` executable that is newer | |||
than the one you attempted to open it with, it is possible that the newer | |||
``dds`` executable performed a schema upgrade that is unsupported by the older | |||
version of ``dds``. | |||
If you have not specified a path to a catalog, ``dds`` will use the user-local | |||
default catalog database. If you receive this error while using the user-local | |||
database, the solution is to either upgrade ``dds`` to match the newer catalog | |||
or to delete the user-local catalog database file. | |||
.. note:: | |||
Deleting the catalog database will lose any customizations that were | |||
contained in that catalog, and they will need to be reconstructed. |
@@ -0,0 +1,7 @@ | |||
Error: Compilation failed | |||
######################### | |||
Receiving this error indicates that the source code compiler exited with an | |||
error. This usually indicates that there is a syntactic or semantic error in | |||
the code that was given to the compiler. Refer to the compiler process's output | |||
for more information. |
@@ -0,0 +1,9 @@ | |||
Error: The build database is corrupted | |||
###################################### | |||
``dds`` stores various data about the local project's build in a database file | |||
kept in the build output directory (default is ``_build``). The file is named | |||
``.dds.db``, and can be safely deleted with no ill effects on the project. | |||
This error is not caused by regular user action, and is probably a bug in | |||
``dds``. If you see this error message frequently, please file a bug report. |
@@ -0,0 +1,17 @@ | |||
Error: The catalog database appears corrupted/invalid | |||
##################################################### | |||
This issue will occur if the schema contained in the catalog database does not | |||
match the schema that ``dds`` expects. This should never occur during normal | |||
use of ``dds``. | |||
.. note:: | |||
If you suspect that ``dds`` has accidentally corrupted its own catalog | |||
database, please file a bug report. | |||
``dds`` cannot reliably repair a corrupted database, and the only solution will | |||
be to either manually fix it or to delete the database file and start fresh. | |||
.. note:: | |||
Deleting the catalog database will lose any customizations that were | |||
contained in that catalog, and they will need to be reconstructed. |
@@ -0,0 +1,22 @@ | |||
Error: A Git ``clone`` operation failed | |||
####################################### | |||
This error indicates that ``dds`` failed to clone a Git repository. | |||
``dds`` will invoke ``git clone`` as a subprocess to retrieve a copy of a | |||
remote repository. There are several reasons this might fail, but it is best | |||
to refer to the output of the ``git`` subprocess to diagnose the issue. | |||
A non-exhaustive list of things to check: | |||
#. Is the ``git`` executable available and on the ``PATH`` environment variable? | |||
#. Is the URL to the repository correct? | |||
#. Is the remote server accessible? | |||
#. Do you have read-access to the repository in question? | |||
#. Does the named tag/branch exist in the remote? | |||
#. If cloning a specific Git revision, does the remote server support cloning | |||
a repository by a specific commit? (Very often Git servers are not | |||
configured to support this capability). | |||
Be aware if you are using SSH-style ``git-clone`` that it will require the | |||
correct SSH keys to be available on the system where ``dds`` is running. |
@@ -0,0 +1,9 @@ | |||
Error: Invalid catalog JSON | |||
########################### | |||
This error occurs when the JSON data given to import into the package catalog | |||
is in some way invalid. Refer to the catalog documentation for a description of | |||
the proper JSON format. | |||
.. seealso:: | |||
:ref:`catalog.adding` |
@@ -0,0 +1,22 @@ | |||
Error: Invalid version string | |||
############################# | |||
``dds`` stores version numbers in a type-safe manner, and all version numbers | |||
are requried to match `Semantic Versioning <https://semver.org>`_. | |||
If you see this error, it means that a ``dds`` found a version number that does | |||
not correctly conform to Semantic Versioning's requirements for version numbers | |||
refer to the ``dds`` output for a description of *where* the bad version string | |||
was found, and refer to the Semantic Versioning website for information about | |||
how to properly format a version number. | |||
.. _range: | |||
Version Ranges | |||
************** | |||
In addition to requirements on individual versions, providing a version range | |||
requires a slightly different syntax. | |||
.. TODO: Write docs on version range strings. |
@@ -0,0 +1,10 @@ | |||
Error: Package is missing remote acquisition information | |||
######################################################## | |||
When a package is being added/imported into the package catalog, ``dds`` | |||
requires some information regarding how to actually *acquire* that package | |||
when it is requested. | |||
If such information is not provided, ``dds`` will issue an error. | |||
.. seealso:: :ref:`catalog.adding`. |
@@ -0,0 +1,18 @@ | |||
Error: The generated source distribution's identity is not correct | |||
################################################################## | |||
When ``dds`` attempts to automatically generate a source distribution, | |||
especially when generating from a remote that was acquired using a catalog | |||
listing, ``dds`` expects the generated source distribution to have a matching | |||
package identity to match what was intended. | |||
This can happen if a catalog listing's package version does not match the | |||
source of the remote acquisition method. For example, if using ``git`` to clone | |||
a repository, the ``git-ref`` used to clone must match the package version of | |||
the listing. If the ``git-ref`` is a branch, it is possible that additional | |||
changes were pushed into the branch that changed the package version, thus | |||
invalidating the package. [#f1]_ | |||
.. [#f1] | |||
For this reason, it is **highly recommended** to use Git *tags* to | |||
refer to remote packages *instead of branches*. |
@@ -46,7 +46,7 @@ void create_archive_plan::archive(const build_env& env) const { | |||
// Check, log, and throw | |||
if (!ar_res.okay()) { | |||
spdlog::error("Creating static library archive failed: {}", out_relpath); | |||
spdlog::error("Creating static library archive [{}] failed for '{}'", out_relpath, _name); | |||
spdlog::error("Subcommand FAILED: {}\n{}", quote_command(ar_cmd), ar_res.output); | |||
throw_external_error< | |||
errc::archive_failure>("Creating static library archive [{}] failed for '{}'", |
@@ -1,6 +1,7 @@ | |||
#include "./compile_exec.hpp" | |||
#include <dds/build/file_deps.hpp> | |||
#include <dds/error/errors.hpp> | |||
#include <dds/proc.hpp> | |||
#include <dds/util/string.hpp> | |||
#include <dds/util/time.hpp> | |||
@@ -180,7 +181,7 @@ do_compile(const compile_file_full& cf, build_env_ref env, compile_counter& coun | |||
if (compile_signal) { | |||
spdlog::error("Process exited via signal {}", compile_signal); | |||
} | |||
throw compile_failure(fmt::format("Compilation failed for {}", source_path.string())); | |||
throw_user_error<errc::compile_failure>("Compilation failed [{}]", source_path.string()); | |||
} | |||
// Print any compiler output, sans whitespace |
@@ -2,6 +2,7 @@ | |||
#include <dds/build/iter_compilations.hpp> | |||
#include <dds/build/plan/compile_exec.hpp> | |||
#include <dds/error/errors.hpp> | |||
#include <range/v3/view/concat.hpp> | |||
#include <range/v3/view/filter.hpp> | |||
@@ -76,7 +77,7 @@ bool parallel_run(Range&& rng, int n_jobs, Fn&& fn) { | |||
void build_plan::compile_all(const build_env& env, int njobs) const { | |||
auto okay = dds::compile_all(iter_compilations(*this), env, njobs); | |||
if (!okay) { | |||
throw std::runtime_error("Compilation failed."); | |||
throw_user_error<errc::compile_failure>(); | |||
} | |||
} | |||
@@ -87,7 +88,7 @@ void build_plan::archive_all(const build_env& env, int njobs) const { | |||
} | |||
}); | |||
if (!okay) { | |||
throw std::runtime_error("Error creating static library archives"); | |||
throw_external_error<errc::archive_failure>(); | |||
} | |||
} | |||
@@ -107,7 +108,7 @@ void build_plan::link_all(const build_env& env, int njobs) const { | |||
exe.get().link(env, lib); | |||
}); | |||
if (!okay) { | |||
throw std::runtime_error("Failure to link executables"); | |||
throw_user_error<errc::link_failure>(); | |||
} | |||
} | |||
@@ -1,5 +1,6 @@ | |||
#include "./catalog.hpp" | |||
#include <dds/error/errors.hpp> | |||
#include <dds/solve/solve.hpp> | |||
#include <neo/sqlite3/exec.hpp> | |||
@@ -75,14 +76,22 @@ void ensure_migrated(sqlite3::database& db) { | |||
auto meta = nlohmann::json::parse(meta_json); | |||
if (!meta.is_object()) { | |||
throw std::runtime_error("Corrupted repository database file."); | |||
throw_external_error<errc::corrupted_catalog_db>(); | |||
} | |||
auto version_ = meta["version"]; | |||
if (!version_.is_number_integer()) { | |||
throw std::runtime_error("Corrupted repository database file [bad dds_meta.version]"); | |||
throw_external_error<errc::corrupted_catalog_db>( | |||
"The catalog database metadata is invalid [bad dds_meta.version]"); | |||
} | |||
constexpr int current_database_version = 1; | |||
int version = version_; | |||
if (version > current_database_version) { | |||
throw_external_error<errc::catalog_too_new>(); | |||
} | |||
if (version < 1) { | |||
migrate_repodb_1(db); | |||
} | |||
@@ -101,10 +110,10 @@ catalog catalog::open(const std::string& db_path) { | |||
ensure_migrated(db); | |||
} catch (const sqlite3::sqlite3_error& e) { | |||
spdlog::critical( | |||
"Failed to load the repository databsae. It appears to be invalid/corrupted. The " | |||
"Failed to load the repository database. It appears to be invalid/corrupted. The " | |||
"exception message is: {}", | |||
e.what()); | |||
throw; | |||
throw_external_error<errc::corrupted_catalog_db>(); | |||
} | |||
return catalog(std::move(db)); | |||
} | |||
@@ -163,10 +172,7 @@ void catalog::store(const package_info& pkg) { | |||
)"_sql); | |||
for (const auto& dep : pkg.deps) { | |||
new_dep_st.reset(); | |||
if (dep.versions.num_intervals() != 1) { | |||
throw std::runtime_error( | |||
"Package dependency may only contain a single version interval"); | |||
} | |||
assert(dep.versions.num_intervals() == 1); | |||
auto iv_1 = *dep.versions.iter_intervals().begin(); | |||
sqlite3::exec(new_dep_st, | |||
std::forward_as_tuple(db_pkg_id, | |||
@@ -274,7 +280,7 @@ namespace { | |||
void check_json(bool b, std::string_view what) { | |||
if (!b) { | |||
throw std::runtime_error("Unable to read repository JSON: " + std::string(what)); | |||
throw_user_error<errc::invalid_catalog_json>("Catalog JSON is invalid: {}", what); | |||
} | |||
} | |||
@@ -337,8 +343,9 @@ void catalog::import_json_str(std::string_view content) { | |||
} | |||
info.remote = git_remote_listing{url, ref, autolib}; | |||
} else { | |||
throw std::runtime_error( | |||
fmt::format("No remote info for /packages/{}/{}", pkg_name, version_)); | |||
throw_user_error<errc::no_catalog_remote_info>("No remote info for /packages/{}/{}", | |||
pkg_name, | |||
version_); | |||
} | |||
store(info); |
@@ -1,6 +1,7 @@ | |||
#include "./get.hpp" | |||
#include <dds/catalog/catalog.hpp> | |||
#include <dds/error/errors.hpp> | |||
#include <dds/proc.hpp> | |||
#include <spdlog/spdlog.h> | |||
@@ -22,11 +23,11 @@ temporary_sdist do_pull_sdist(const package_info& listing, const git_remote_list | |||
tmpdir.path().generic_string()}; | |||
auto git_res = run_proc(command); | |||
if (!git_res.okay()) { | |||
throw std::runtime_error( | |||
fmt::format("Git clone operation failed [Git command: {}] [Exitted {}]:\n{}", | |||
quote_command(command), | |||
git_res.retc, | |||
git_res.output)); | |||
throw_external_error<errc::git_clone_failure>( | |||
"Git clone operation failed [Git command: {}] [Exitted {}]:\n{}", | |||
quote_command(command), | |||
git_res.retc, | |||
git_res.output); | |||
} | |||
spdlog::info("Create sdist from clone ..."); | |||
if (git.auto_lib.has_value()) { | |||
@@ -53,11 +54,11 @@ temporary_sdist do_pull_sdist(const package_info& listing, const git_remote_list | |||
temporary_sdist dds::get_package_sdist(const package_info& pkg) { | |||
auto tsd = std::visit([&](auto&& remote) { return do_pull_sdist(pkg, remote); }, pkg.remote); | |||
if (!(tsd.sdist.manifest.pkg_id == pkg.ident)) { | |||
throw std::runtime_error(fmt::format( | |||
"The package name@version in the generated sdist does not match the name listed in " | |||
"the remote listing file (expected '{}', but got '{}')", | |||
throw_external_error<errc::sdist_ident_mismatch>( | |||
"The package name@version in the generated source distribution does not match the name " | |||
"listed in the remote listing file (expected '{}', but got '{}')", | |||
pkg.ident.to_string(), | |||
tsd.sdist.manifest.pkg_id.to_string())); | |||
tsd.sdist.manifest.pkg_id.to_string()); | |||
} | |||
return tsd; | |||
} |
@@ -1,5 +1,7 @@ | |||
#include "./database.hpp" | |||
#include <dds/error/errors.hpp> | |||
#include <neo/sqlite3/exec.hpp> | |||
#include <neo/sqlite3/iter_tuples.hpp> | |||
#include <neo/sqlite3/single.hpp> | |||
@@ -62,12 +64,13 @@ void ensure_migrated(sqlite3::database& db) { | |||
auto meta = nlohmann::json::parse(meta_json); | |||
if (!meta.is_object()) { | |||
throw std::runtime_error("Correupted database file."); | |||
throw_external_error<errc::corrupted_build_db>(); | |||
} | |||
auto version_ = meta["version"]; | |||
if (!version_.is_number_integer()) { | |||
throw std::runtime_error("Corrupted database file [bad dds_meta.version]"); | |||
throw_external_error<errc::corrupted_build_db>( | |||
"The build database file is corrupted [bad dds_meta.version]"); | |||
} | |||
int version = version_; | |||
if (version < 1) { |
@@ -1,5 +1,6 @@ | |||
#include "./deps.hpp" | |||
#include <dds/error/errors.hpp> | |||
#include <dds/repo/repo.hpp> | |||
#include <dds/source/dist.hpp> | |||
#include <dds/usage_reqs.hpp> | |||
@@ -34,11 +35,8 @@ dependency dependency::parse_depends_string(std::string_view str) { | |||
auto rng = semver::range::parse_restricted(version_str); | |||
return dependency{std::string(name), {rng.low(), rng.high()}}; | |||
} catch (const semver::invalid_range&) { | |||
throw std::runtime_error(fmt::format( | |||
"Invalid version range string '{}' in dependency declaration '{}' (Should be a " | |||
"semver range string. See https://semver.org/ for info)", | |||
version_str, | |||
str)); | |||
throw_user_error<errc::invalid_version_range_string>( | |||
"Invalid version range string '{}' in dependency declaration '{}'", version_str, str); | |||
} | |||
} | |||
@@ -19,10 +19,30 @@ std::string error_url_suffix(dds::errc ec) noexcept { | |||
return "git-url-ref-mutual-req.html"; | |||
case errc::test_failure: | |||
return "test-failure.html"; | |||
case errc::compile_failure: | |||
return "compile-failure.html"; | |||
case errc::archive_failure: | |||
return "archive-failure.html"; | |||
case errc::link_failure: | |||
return "link-failure.html"; | |||
case errc::catalog_too_new: | |||
return "catalog-too-new.html"; | |||
case errc::corrupted_catalog_db: | |||
return "corrupted-catalog-db.html"; | |||
case errc::invalid_catalog_json: | |||
return "invalid-catalog-json.html"; | |||
case errc::no_catalog_remote_info: | |||
return "no-catalog-remote-info.html"; | |||
case errc::git_clone_failure: | |||
return "git-clone-failure.html"; | |||
case errc::sdist_ident_mismatch: | |||
return "sdist-ident-mismatch.html"; | |||
case errc::corrupted_build_db: | |||
return "corrupted-build-db.html"; | |||
case errc::invalid_version_range_string: | |||
return "invalid-version-string.html#range"; | |||
case errc::invalid_version_string: | |||
return "invalid-version-string.html"; | |||
case errc::none: | |||
break; | |||
} | |||
@@ -61,6 +81,10 @@ reference (tag, branch, commit) to clone. | |||
return R"( | |||
One or more of the project's tests failed. The failing tests are listed above, | |||
along with their exit code and output. | |||
)"; | |||
case errc::compile_failure: | |||
return R"( | |||
Source compilation failed. Refer to the compiler output. | |||
)"; | |||
case errc::archive_failure: | |||
return R"( | |||
@@ -75,6 +99,59 @@ fail. Refer to the output of the archiving tool. | |||
return R"( | |||
Linking a runtime binary file failed. There are a variety of possible causes | |||
for this error. Refer to the documentation for more information. | |||
)"; | |||
case errc::catalog_too_new: | |||
return R"( | |||
The catalog database file contains a schema that will automatically be upgraded | |||
by dds when it is opened/modified. It appears that the given catalog database | |||
has had a migration beyond a version that we support. Has the catalog been | |||
modified by a newer version of dds? | |||
)"; | |||
case errc::corrupted_catalog_db: | |||
return R"( | |||
The catalog database schema doesn't match what dds expects. This indicates that | |||
the database file has been modified in a way that dds cannot automatically fix | |||
and handle. | |||
)"; | |||
case errc::invalid_catalog_json: | |||
return R"( | |||
The catalog JSON that was provided does not match the format that was expected. | |||
Check the JSON schema and try your submission again. | |||
)"; | |||
case errc::no_catalog_remote_info: | |||
return R"( | |||
The catalog entry requires information regarding the remote acquisition method. | |||
Refer to the documentation for details. | |||
)"; | |||
case errc::git_clone_failure: | |||
return R"( | |||
dds tried to clone a repository using Git, but the clone operation failed. | |||
There are a variety of possible causes. It is best to check the output from | |||
Git in diagnosing this failure. | |||
)"; | |||
case errc::sdist_ident_mismatch: | |||
return R"( | |||
We tried to automatically generate a source distribution from a package, but | |||
the name and/or version of the package that was generated does not match what | |||
we expected of it. | |||
)"; | |||
case errc::corrupted_build_db: | |||
return R"( | |||
The local build database file is corrupted. The file is stored in the build | |||
directory as `.dds.db', and is safe to delete to clear the bad data. This is | |||
not a likely error, and if you receive this message frequently, please file a | |||
bug report. | |||
)"; | |||
case errc::invalid_version_range_string: | |||
return R"( | |||
Parsing of a version range string failed. Refer to the documentation for more | |||
information. | |||
)"; | |||
case errc::invalid_version_string: | |||
return R"( | |||
`dds` expects all version numbers to conform to the Semantic Versioning | |||
specification. Refer to the documentation and https://semver.org/ for more | |||
information. | |||
)"; | |||
case errc::none: | |||
break; | |||
@@ -93,10 +170,34 @@ std::string_view dds::default_error_string(dds::errc ec) noexcept { | |||
return "Git requires both a URL and a ref to clone"; | |||
case errc::test_failure: | |||
return "One or more tests failed"; | |||
case errc::compile_failure: | |||
return "Source compilation failed."; | |||
case errc::archive_failure: | |||
return "Creating a static library archive failed"; | |||
case errc::link_failure: | |||
return "Linking a runtime binary (executable/shared library/DLL) failed"; | |||
case errc::catalog_too_new: | |||
return "The catalog appears to be from a newer version of dds."; | |||
case errc::corrupted_catalog_db: | |||
return "The catalog database appears to be corrupted or invalid"; | |||
case errc::invalid_catalog_json: | |||
return "The given catalog JSON data is not valid"; | |||
case errc::no_catalog_remote_info: | |||
return "The catalog JSON is missing remote acquisition information for one or more\n" | |||
"packages"; | |||
case errc::git_clone_failure: | |||
return "A git-clone operation failed."; | |||
case errc::sdist_ident_mismatch: | |||
return "The package version of a generated source distribution did not match the version\n" | |||
"that was expected of it"; | |||
case errc::corrupted_build_db: | |||
return "The build database file is corrupted"; | |||
case errc::invalid_version_range_string: | |||
return "Attempted to parse an invalid version range string. <- (Seeing this text is a " | |||
"`dds` bug. Please report it.)"; | |||
case errc::invalid_version_string: | |||
return "Attempted to parse an invalid version string. <- (Seeing this text is a `dds` bug. " | |||
"Please report it.)"; | |||
case errc::none: | |||
break; | |||
} |
@@ -13,8 +13,22 @@ enum class errc { | |||
no_such_catalog_package, | |||
git_url_ref_mutual_req, | |||
test_failure, | |||
compile_failure, | |||
archive_failure, | |||
link_failure, | |||
catalog_too_new, | |||
corrupted_catalog_db, | |||
invalid_catalog_json, | |||
no_catalog_remote_info, | |||
git_clone_failure, | |||
sdist_ident_mismatch, | |||
corrupted_build_db, | |||
invalid_version_range_string, | |||
invalid_version_string, | |||
}; | |||
std::string error_reference_of(errc) noexcept; |