Browse Source

New throw_user_errors for better error messages

default_compile_flags
vector-of-bool 4 years ago
parent
commit
5a2a91659f
8 changed files with 90 additions and 19 deletions
  1. +56
    -0
      src/dds/error/errors.cpp
  2. +6
    -0
      src/dds/error/errors.hpp
  3. +5
    -3
      src/dds/package/id.cpp
  4. +5
    -4
      src/dds/package/manifest.cpp
  5. +2
    -1
      src/dds/repo/repo.cpp
  6. +3
    -1
      src/dds/solve/solve.cpp
  7. +2
    -2
      src/dds/source/dist.cpp
  8. +11
    -8
      src/dds/usage_reqs.cpp

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

return "invalid-pkg-filesystem.html"; return "invalid-pkg-filesystem.html";
case errc::unknown_test_driver: case errc::unknown_test_driver:
return "unknown-test-driver.html"; return "unknown-test-driver.html";
case errc::invalid_pkg_name:
case errc::invalid_pkg_id:
return "invalid-pkg-ident.html";
case errc::sdist_exists:
return "sdist-exists.html";
case errc::dependency_resolve_failure:
return "dep-res-failure.html";
case errc::dup_lib_name:
return "dup-lib-name.html";
case errc::unknown_usage_name:
return "unknown-usage.html";
case errc::none: case errc::none:
break; break;
} }
return R"( return R"(
`dds` has a pre-defined set of built-in test drivers, and the one specified is `dds` has a pre-defined set of built-in test drivers, and the one specified is
not recognized. Check the documentation for more information. not recognized. Check the documentation for more information.
)";
case errc::invalid_pkg_id:
return R"(Package IDs must follow a strict format of <name>@<version>.)";
case errc::invalid_pkg_name:
return R"(Package names allow a limited set of characters and must not be empty.)";
case errc::sdist_exists:
return R"(
By default, `dds` will not overwrite source distributions that already exist
(either in the repository or a filesystem path). Such an action could
potentially destroy important data.
)";
case errc::dependency_resolve_failure:
return R"(
The dependency resolution algorithm failed to resolve the requirements of the
project. The algorithm's explanation should give enough information to infer
why there is no possible solution. You may need to reconsider your dependency
versions to avoid conflicts.
)";
case errc::dup_lib_name:
return R"(
`dds` cannot build code correctly when there is more than one library that has
claimed the same name. It is possible that the duplicate name appears in a
dependency and is not an issue in your own project. Consult the output to see
which packages are claiming the library name.
)";
case errc::unknown_usage_name:
return R"(
A `Uses` or `Links` field for a library specifies a library of an unknown name.
Check your spelling, and check that the package containing the library is
available, either from the `package.dds` or from the `INDEX.lmi` that was used
for the build.
)"; )";
case errc::none: case errc::none:
break; break;
case errc::invalid_pkg_filesystem: case errc::invalid_pkg_filesystem:
return "The filesystem structure of the package/library is invalid. <- (Seeing this text " return "The filesystem structure of the package/library is invalid. <- (Seeing this text "
"is a `dds` bug. Please report it.)"; "is a `dds` bug. Please report it.)";
case errc::invalid_pkg_id:
return "A package identifier is invalid <- (Seeing this text is a `dds` bug. Please "
"report it.)";
case errc::invalid_pkg_name:
return "A package name is invalid <- (Seeing this text is a `dds` bug. Please report it.)";
case errc::sdist_exists:
return "The source ditsribution already exists at the destination <- (Seeing this text is "
"a `dds` bug. Please report it.)";
case errc::unknown_test_driver: case errc::unknown_test_driver:
return "The specified Test-Driver is not known to `dds`"; return "The specified Test-Driver is not known to `dds`";
case errc::dependency_resolve_failure:
return "`dds` was unable to find a solution for the package dependencies given.";
case errc::dup_lib_name:
return "More than one library has claimed the same name.";
case errc::unknown_usage_name:
return "A `Uses` or `Links` field names a library that isn't recognized.";
case errc::none: case errc::none:
break; break;
} }

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



git_clone_failure, git_clone_failure,
sdist_ident_mismatch, sdist_ident_mismatch,
sdist_exists,


corrupted_build_db, corrupted_build_db,


invalid_version_range_string, invalid_version_range_string,
invalid_version_string, invalid_version_string,
invalid_pkg_id,
invalid_pkg_name,
invalid_config_key, invalid_config_key,
unknown_test_driver, unknown_test_driver,
dependency_resolve_failure,
dup_lib_name,
unknown_usage_name,


invalid_lib_filesystem, invalid_lib_filesystem,
invalid_pkg_filesystem, invalid_pkg_filesystem,

+ 5
- 3
src/dds/package/id.cpp View File

#include <dds/package/id.hpp> #include <dds/package/id.hpp>


#include <dds/error/errors.hpp>

#include <spdlog/fmt/fmt.h> #include <spdlog/fmt/fmt.h>


#include <tuple> #include <tuple>
package_id package_id::parse(std::string_view s) { package_id package_id::parse(std::string_view s) {
auto at_pos = s.find('@'); auto at_pos = s.find('@');
if (at_pos == s.npos) { if (at_pos == s.npos) {
throw std::runtime_error(fmt::format("Invalid package ID string '{}'", s));
throw_user_error<errc::invalid_pkg_id>("Invalid package ID '{}'", s);
} }


auto name = s.substr(0, at_pos); auto name = s.substr(0, at_pos);
: name(n) : name(n)
, version(std::move(v)) { , version(std::move(v)) {
if (name.find('@') != name.npos) { if (name.find('@') != name.npos) {
throw std::runtime_error(
fmt::format("Invalid package name '{}' (The '@' character is not allowed)"));
throw_user_error<errc::invalid_pkg_name>(
"Invalid package name '{}' (The '@' character is not allowed)");
} }
} }



+ 5
- 4
src/dds/package/manifest.cpp View File

lm_reject_dym{{"Name", "Namespace", "Version", "Depends", "Test-Driver"}}); lm_reject_dym{{"Name", "Namespace", "Version", "Depends", "Test-Driver"}});


if (ret.pkg_id.name.empty()) { if (ret.pkg_id.name.empty()) {
throw std::runtime_error(
fmt::format("'Name' field in [{}] may not be an empty string", fpath.string()));
throw_user_error<errc::invalid_pkg_name>("'Name' field in [{}] may not be an empty string",
fpath.string());
} }
if (version_str.empty()) { if (version_str.empty()) {
throw std::runtime_error(
fmt::format("'Version' field in [{}] may not be an empty string", fpath.string()));
throw_user_error<
errc::invalid_version_string>("'Version' field in [{}] may not be an empty string",
fpath.string());
} }
if (opt_test_driver) { if (opt_test_driver) {
auto& test_driver_str = *opt_test_driver; auto& test_driver_str = *opt_test_driver;

+ 2
- 1
src/dds/repo/repo.cpp View File

#include "./repo.hpp" #include "./repo.hpp"


#include <dds/catalog/catalog.hpp> #include <dds/catalog/catalog.hpp>
#include <dds/error/errors.hpp>
#include <dds/solve/solve.hpp> #include <dds/solve/solve.hpp>
#include <dds/source/dist.hpp> #include <dds/source/dist.hpp>
#include <dds/util/paths.hpp> #include <dds/util/paths.hpp>
auto msg = fmt::format("Source distribution '{}' is already available in the local repo", auto msg = fmt::format("Source distribution '{}' is already available in the local repo",
sd.path.string()); sd.path.string());
if (ife_action == if_exists::throw_exc) { if (ife_action == if_exists::throw_exc) {
throw std::runtime_error(msg);
throw_user_error<errc::sdist_exists>(msg);
} else if (ife_action == if_exists::ignore) { } else if (ife_action == if_exists::ignore) {
spdlog::warn(msg); spdlog::warn(msg);
return; return;

+ 3
- 1
src/dds/solve/solve.cpp View File

#include "./solve.hpp" #include "./solve.hpp"


#include <dds/error/errors.hpp>

#include <pubgrub/solve.hpp> #include <pubgrub/solve.hpp>


#include <range/v3/range/conversion.hpp> #include <range/v3/range/conversion.hpp>
} catch (const solve_fail_exc& failure) { } catch (const solve_fail_exc& failure) {
spdlog::error("Dependency resolution has failed! Explanation:"); spdlog::error("Dependency resolution has failed! Explanation:");
pubgrub::generate_explaination(failure, explainer()); pubgrub::generate_explaination(failure, explainer());
throw;
throw_user_error<errc::dependency_resolve_failure>();
} }
} }

+ 2
- 2
src/dds/source/dist.cpp View File

auto dest = fs::absolute(params.dest_path); auto dest = fs::absolute(params.dest_path);
if (fs::exists(dest)) { if (fs::exists(dest)) {
if (!params.force) { if (!params.force) {
throw std::runtime_error(
fmt::format("Destination path '{}' already exists", dest.string()));
throw_user_error<errc::sdist_exists>("Destination path '{}' already exists",
dest.string());
} }
} }



+ 11
- 8
src/dds/usage_reqs.cpp View File

#include "./usage_reqs.hpp" #include "./usage_reqs.hpp"


#include <dds/build/plan/compile_file.hpp> #include <dds/build/plan/compile_file.hpp>
#include <dds/error/errors.hpp>
#include <dds/util/algo.hpp> #include <dds/util/algo.hpp>


#include <spdlog/fmt/fmt.h> #include <spdlog/fmt/fmt.h>
auto pair = std::pair(library_key{ns, name}, lm::library{}); auto pair = std::pair(library_key{ns, name}, lm::library{});
auto [inserted, did_insert] = _reqs.try_emplace(library_key{ns, name}, lm::library()); auto [inserted, did_insert] = _reqs.try_emplace(library_key{ns, name}, lm::library());
if (!did_insert) { if (!did_insert) {
throw std::runtime_error(
fmt::format("More than one library is registered as {}/{}", ns, name));
throw_user_error<errc::dup_lib_name>("More than one library is registered as `{}/{}'",
ns,
name);
} }
return inserted->second; return inserted->second;
} }
std::vector<fs::path> usage_requirement_map::link_paths(const lm::usage& key) const { std::vector<fs::path> usage_requirement_map::link_paths(const lm::usage& key) const {
auto req = get(key); auto req = get(key);
if (!req) { if (!req) {
throw std::runtime_error(
fmt::format("Unable to find linking requirement '{}/{}'", key.namespace_, key.name));
throw_user_error<errc::unknown_usage_name>("Unable to find linking requirement '{}/{}'",
key.namespace_,
key.name);
} }
std::vector<fs::path> ret; std::vector<fs::path> ret;
if (req->linkable_path) { if (req->linkable_path) {
std::vector<fs::path> ret; std::vector<fs::path> ret;
auto lib = get(usage.namespace_, usage.name); auto lib = get(usage.namespace_, usage.name);
if (!lib) { if (!lib) {
throw std::runtime_error(
fmt::format("Cannot find non-existent usage requirements for '{}/{}'",
usage.namespace_,
usage.name));
throw_user_error<
errc::unknown_usage_name>("Cannot find non-existent usage requirements for '{}/{}'",
usage.namespace_,
usage.name);
} }
extend(ret, lib->include_paths); extend(ret, lib->include_paths);
for (const auto& transitive : lib->uses) { for (const auto& transitive : lib->uses) {

Loading…
Cancel
Save