Browse Source

More errors!

default_compile_flags
vector-of-bool 4 years ago
parent
commit
137bfca94d
18 changed files with 293 additions and 32 deletions
  1. +21
    -0
      docs/err/catalog-too-new.rst
  2. +7
    -0
      docs/err/compile-failure.rst
  3. +9
    -0
      docs/err/corrupted-build-db.rst
  4. +17
    -0
      docs/err/corrupted-catalog-db.rst
  5. +22
    -0
      docs/err/git-clone-failure.rst
  6. +9
    -0
      docs/err/invalid-catalog-json.rst
  7. +22
    -0
      docs/err/invalid-version-string.rst
  8. +10
    -0
      docs/err/no-catalog-remote-info.rst
  9. +18
    -0
      docs/err/sdist-ident-mismatch.rst
  10. +1
    -1
      src/dds/build/plan/archive.cpp
  11. +2
    -1
      src/dds/build/plan/compile_exec.cpp
  12. +4
    -3
      src/dds/build/plan/full.cpp
  13. +18
    -11
      src/dds/catalog/catalog.cpp
  14. +10
    -9
      src/dds/catalog/get.cpp
  15. +5
    -2
      src/dds/db/database.cpp
  16. +3
    -5
      src/dds/deps.cpp
  17. +101
    -0
      src/dds/error/errors.cpp
  18. +14
    -0
      src/dds/error/errors.hpp

+ 21
- 0
docs/err/catalog-too-new.rst View File

@@ -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.

+ 7
- 0
docs/err/compile-failure.rst View File

@@ -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.

+ 9
- 0
docs/err/corrupted-build-db.rst View File

@@ -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.

+ 17
- 0
docs/err/corrupted-catalog-db.rst View File

@@ -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.

+ 22
- 0
docs/err/git-clone-failure.rst View File

@@ -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.

+ 9
- 0
docs/err/invalid-catalog-json.rst View File

@@ -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`

+ 22
- 0
docs/err/invalid-version-string.rst View File

@@ -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.

+ 10
- 0
docs/err/no-catalog-remote-info.rst View File

@@ -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`.

+ 18
- 0
docs/err/sdist-ident-mismatch.rst View File

@@ -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*.

+ 1
- 1
src/dds/build/plan/archive.cpp View File

@@ -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 '{}'",

+ 2
- 1
src/dds/build/plan/compile_exec.cpp View File

@@ -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

+ 4
- 3
src/dds/build/plan/full.cpp View File

@@ -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>();
}
}


+ 18
- 11
src/dds/catalog/catalog.cpp View File

@@ -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);

+ 10
- 9
src/dds/catalog/get.cpp View File

@@ -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;
}

+ 5
- 2
src/dds/db/database.cpp View File

@@ -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) {

+ 3
- 5
src/dds/deps.cpp View File

@@ -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);
}
}


+ 101
- 0
src/dds/error/errors.cpp View File

@@ -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;
}

+ 14
- 0
src/dds/error/errors.hpp View File

@@ -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;

Loading…
Cancel
Save