| 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: | |||||
| * |
| 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`. |
| 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`. |
| list the IDs of the packages, but none of the additional metadata about them. | list the IDs of the packages, but none of the additional metadata about them. | ||||
| .. _catalog.adding: | |||||
| Adding Packages to the Catalog | Adding Packages to the Catalog | ||||
| ****************************** | ****************************** | ||||
| Alternatively, you can pass the name of a built-in toolchain. See below. | Alternatively, you can pass the name of a built-in toolchain. See below. | ||||
| .. _toolchains.builtin: | |||||
| Built-in Toolchains | Built-in Toolchains | ||||
| ******************* | ******************* | ||||
| tut/index | tut/index | ||||
| guide/index | guide/index | ||||
| design | 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 | Indices and tables |
| #include <dds/build/builder.hpp> | #include <dds/build/builder.hpp> | ||||
| #include <dds/catalog/catalog.hpp> | #include <dds/catalog/catalog.hpp> | ||||
| #include <dds/catalog/get.hpp> | #include <dds/catalog/get.hpp> | ||||
| #include <dds/error/errors.hpp> | |||||
| #include <dds/repo/repo.hpp> | #include <dds/repo/repo.hpp> | ||||
| #include <dds/source/dist.hpp> | #include <dds/source/dist.hpp> | ||||
| #include <dds/toolchain/from_dds.hpp> | #include <dds/toolchain/from_dds.hpp> | ||||
| auto default_tc = tc_path.substr(1); | auto default_tc = tc_path.substr(1); | ||||
| auto tc = dds::toolchain::get_builtin(default_tc); | auto tc = dds::toolchain::get_builtin(default_tc); | ||||
| if (!tc.has_value()) { | 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); | return std::move(*tc); | ||||
| } else { | } else { | ||||
| auto id = dds::package_id::parse(req); | auto id = dds::package_id::parse(req); | ||||
| auto info = cat.get(id); | auto info = cat.get(id); | ||||
| if (!info) { | 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 tsd = dds::get_package_sdist(*info); | ||||
| auto out_path = out.Get(); | auto out_path = out.Get(); | ||||
| } catch (const dds::user_cancelled&) { | } catch (const dds::user_cancelled&) { | ||||
| spdlog::critical("Operation cancelled by user"); | spdlog::critical("Operation cancelled by user"); | ||||
| return 2; | 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) { | } catch (const std::exception& e) { | ||||
| spdlog::critical(e.what()); | spdlog::critical(e.what()); | ||||
| return 2; | return 2; |
| #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(); | |||||
| } |
| #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 |