@@ -0,0 +1,18 @@ | |||
Runtime Error References | |||
######################## | |||
This page enumerates the possible errors that you may encounter while using | |||
DDS, either from user error or environmental issues. | |||
.. note:: | |||
DDS will automatically emit links to the relevant error document when it | |||
occurs. | |||
Errors | |||
****** | |||
.. toctree:: | |||
:maxdepth: 2 | |||
:glob: | |||
* |
@@ -0,0 +1,17 @@ | |||
Error: Invalid built-in toolchain | |||
################################# | |||
``dds`` requires a toolchain in order to build any packages or projects. It | |||
ships with several built-in toolchains that do not require the user to write | |||
any configuration files. | |||
If you start your toolchain name (The `-t` or `--toolchain` argument) | |||
with a leading colon, dds will interpret it as a reference to a built-in | |||
toolchain. (Toolchain file paths cannot begin with a leading colon). | |||
These toolchain names are encoded into the dds executable and cannot be | |||
modified. | |||
.. seealso:: | |||
Refer to the documentation on :doc:`toolchains </guide/toolchains>` and | |||
:ref:`toolchains.builtin`. |
@@ -0,0 +1,17 @@ | |||
Error: No such package in the catalog | |||
##################################### | |||
This error will occur when one attempts to obtain a package from the package | |||
catalog by its specific ``name@version`` pair, but no such entry exists | |||
in the catalog. | |||
It is possible that the intended package *does exist* but that the spelling of | |||
the package name or version number is incorrect. Firstly, check your spelling | |||
and that the version number you have requested is correct. | |||
In another case, it is possible that the package *exists somewhere*, but has | |||
not been loaded into the local catalog. As of this writing, ``dds`` does not | |||
automatically maintain the catalog against a central package repository, so | |||
package entries must be loaded and imported manually. If you believe this to be | |||
the case, refer to the section on the :doc:`/guide/catalog`, especially the | |||
section :ref:`catalog.adding`. |
@@ -14,6 +14,8 @@ package IDs available can be listed with ``dds catalog list``. This will only | |||
list the IDs of the packages, but none of the additional metadata about them. | |||
.. _catalog.adding: | |||
Adding Packages to the Catalog | |||
****************************** | |||
@@ -42,6 +42,8 @@ toolchain file for the ``--toolchain`` (or ``-t``) option on the command line:: | |||
Alternatively, you can pass the name of a built-in toolchain. See below. | |||
.. _toolchains.builtin: | |||
Built-in Toolchains | |||
******************* | |||
@@ -17,6 +17,14 @@ the :doc:`tut/index` page. | |||
tut/index | |||
guide/index | |||
design | |||
err/index | |||
.. Hide the link to the error reference since we don't want it cluttering our | |||
main toc, but we want Sphinx to not consider it "unreferenced." We'll generate | |||
our own link | |||
.. seealso:: | |||
For in-depth error and troubleshooting information see: :doc:`err/index`. | |||
Indices and tables |
@@ -1,6 +1,7 @@ | |||
#include <dds/build/builder.hpp> | |||
#include <dds/catalog/catalog.hpp> | |||
#include <dds/catalog/get.hpp> | |||
#include <dds/error/errors.hpp> | |||
#include <dds/repo/repo.hpp> | |||
#include <dds/source/dist.hpp> | |||
#include <dds/toolchain/from_dds.hpp> | |||
@@ -38,8 +39,9 @@ struct toolchain_flag : string_flag { | |||
auto default_tc = tc_path.substr(1); | |||
auto tc = dds::toolchain::get_builtin(default_tc); | |||
if (!tc.has_value()) { | |||
throw std::runtime_error( | |||
fmt::format("Invalid default toolchain name '{}'", default_tc)); | |||
dds::throw_user_error< | |||
dds::errc::invalid_builtin_toolchain>("Invalid built-in toolchain name '{}'", | |||
default_tc); | |||
} | |||
return std::move(*tc); | |||
} else { | |||
@@ -190,8 +192,8 @@ struct cli_catalog { | |||
auto id = dds::package_id::parse(req); | |||
auto info = cat.get(id); | |||
if (!info) { | |||
throw std::runtime_error( | |||
fmt::format("No package in the catalog matched the ID '{}'", req)); | |||
dds::throw_user_error<dds::errc::no_such_catalog_package>( | |||
"No package in the catalog matched the ID '{}'", req); | |||
} | |||
auto tsd = dds::get_package_sdist(*info); | |||
auto out_path = out.Get(); | |||
@@ -719,6 +721,11 @@ int main(int argc, char** argv) { | |||
} catch (const dds::user_cancelled&) { | |||
spdlog::critical("Operation cancelled by user"); | |||
return 2; | |||
} catch (const dds::user_error_base& e) { | |||
spdlog::error("{}", e.what()); | |||
spdlog::error("{}", e.explanation()); | |||
spdlog::error("Refer: {}", e.error_reference()); | |||
return 1; | |||
} catch (const std::exception& e) { | |||
spdlog::critical(e.what()); | |||
return 2; |
@@ -0,0 +1,52 @@ | |||
#include "./errors.hpp" | |||
#include <cassert> | |||
#include <stdexcept> | |||
using namespace dds; | |||
namespace { | |||
std::string error_url_prefix = "http://localhost:3000/err/"; | |||
std::string error_url_suffix(dds::errc ec) noexcept { | |||
switch (ec) { | |||
case errc::invalid_builtin_toolchain: | |||
return "invalid-builtin-toolchain.html"; | |||
case errc::no_such_catalog_package: | |||
return "no-such-catalog-package.html"; | |||
case errc::none: | |||
break; | |||
} | |||
assert(false && "Unreachable code path generating error explanation URL"); | |||
std::terminate(); | |||
} | |||
} // namespace | |||
std::string dds::error_reference_of(dds::errc ec) noexcept { | |||
return error_url_prefix + error_url_suffix(ec); | |||
} | |||
std::string_view dds::explanation_of(dds::errc ec) noexcept { | |||
switch (ec) { | |||
case errc::invalid_builtin_toolchain: | |||
return R"( | |||
If you start your toolchain name (The `-t` or `--toolchain` argument) | |||
with a leading colon, dds will interpret it as a reference to a built-in | |||
toolchain. (Toolchain file paths cannot begin with a leading colon). | |||
These toolchain names are encoded into the dds executable and cannot be | |||
modified. | |||
)"; | |||
case errc::no_such_catalog_package: | |||
return R"( | |||
The installation of a package was requested, but the given package ID was not | |||
able to be found in the package catalog. Check the spelling and version number. | |||
)"; | |||
case errc::none: | |||
break; | |||
} | |||
assert(false && "Unexpected execution path during error explanation. This is a DDS bug"); | |||
std::terminate(); | |||
} |
@@ -0,0 +1,45 @@ | |||
#pragma once | |||
#include <spdlog/fmt/fmt.h> | |||
#include <stdexcept> | |||
#include <string_view> | |||
namespace dds { | |||
struct exception_base : std::runtime_error { | |||
using runtime_error::runtime_error; | |||
}; | |||
struct user_error_base : exception_base { | |||
using exception_base::exception_base; | |||
virtual std::string error_reference() const noexcept = 0; | |||
virtual std::string_view explanation() const noexcept = 0; | |||
}; | |||
enum class errc { | |||
none = 0, | |||
invalid_builtin_toolchain, | |||
no_such_catalog_package, | |||
}; | |||
std::string error_reference_of(errc) noexcept; | |||
std::string_view explanation_of(errc) noexcept; | |||
template <errc ErrorCode> | |||
struct user_error : user_error_base { | |||
using user_error_base::user_error_base; | |||
std::string error_reference() const noexcept override { return error_reference_of(ErrorCode); } | |||
std::string_view explanation() const noexcept override { return explanation_of(ErrorCode); } | |||
}; | |||
using error_invalid_default_toolchain = user_error<errc::invalid_builtin_toolchain>; | |||
template <errc ErrorCode, typename... Args> | |||
[[noreturn]] void throw_user_error(std::string_view fmt_str, Args&&... args) { | |||
throw user_error<ErrorCode>(fmt::format(fmt_str, std::forward<Args>(args)...)); | |||
} | |||
} // namespace dds |