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