错误处理统一模式

This commit is contained in:
2026-08-16 12:31:28 +08:00
parent 5e57528ecc
commit 00a3c54820
6 changed files with 93 additions and 12 deletions
@@ -0,0 +1,51 @@
#include "Error_Policy.hpp"
#include <cstdio>
#include <cstdlib>
#include <cstring>
namespace renderive::error {
namespace {
Mode read_mode() noexcept {
const char* value = std::getenv("RENDERIVE_ERROR_MODE");
if (value && std::strcmp(value, "exception") == 0)
return Mode::exception;
return Mode::fast_fail;
}
void print_exception(std::exception_ptr exception) noexcept {
if (!exception)
return;
try {
std::rethrow_exception(exception);
} catch (const std::exception& value) {
std::fprintf(stderr, ": %s", value.what());
} catch (...) {
std::fprintf(stderr, ": unknown exception");
}
}
}
Mode mode() noexcept {
static const Mode value = read_mode();
return value;
}
[[noreturn]] void fast_fail(std::string_view message) noexcept {
std::fprintf(stderr, "Renderive unexpected error: %.*s\n", static_cast<int>(message.size()), message.data());
std::fflush(stderr);
std::abort();
}
[[noreturn]] void fast_fail(std::string_view context, std::exception_ptr exception) noexcept {
std::fprintf(stderr, "Renderive unexpected error");
if (!context.empty())
std::fprintf(stderr, " during %.*s", static_cast<int>(context.size()), context.data());
print_exception(exception);
std::fprintf(stderr, "\n");
std::fflush(stderr);
std::abort();
}
[[noreturn]] void unexpected(std::string_view context, std::exception_ptr exception) {
if (mode() == Mode::exception) {
if (exception)
std::rethrow_exception(exception);
throw std::runtime_error(context.empty() ? "Renderive unexpected error" : std::string(context));
}
fast_fail(context, exception);
}
}
@@ -0,0 +1,27 @@
#pragma once
#include <exception>
#include <stdexcept>
#include <string>
#include <string_view>
#include <utility>
namespace renderive::error {
enum class Mode {
fast_fail,
exception
};
[[nodiscard]] Mode mode() noexcept;
[[noreturn]] void fast_fail(std::string_view message) noexcept;
[[noreturn]] void fast_fail(std::string_view context, std::exception_ptr exception) noexcept;
[[noreturn]] void unexpected(std::string_view context, std::exception_ptr exception);
template <class Exception = std::runtime_error, class... Arguments>
[[noreturn]] void unexpected(Arguments&&... arguments) {
if (mode() == Mode::exception)
throw Exception(std::forward<Arguments>(arguments)...);
try {
Exception exception(std::forward<Arguments>(arguments)...);
fast_fail(exception.what());
} catch (...) {
fast_fail("Renderive unexpected error");
}
}
}
@@ -1,4 +1,5 @@
#include "Scene_Base.hpp"
#include "renderive/error/Error_Policy.hpp"
#include <algorithm>
#include <chrono>
@@ -86,7 +87,7 @@ public:
const std::size_t queued = queued_.fetch_add(1, std::memory_order_relaxed) + 1;
update_peak(peak_queued_, queued);
if (!operations_.try_push(std::move(operation)))
std::terminate();
renderive::error::unexpected<std::logic_error>("scene execution queue rejected admitted operation");
schedule();
}
void wait() noexcept {
@@ -1124,9 +1125,9 @@ const Frame_Control_Strategy_Base& Scene_Base::frame_control_strategy() const {
}
void Scene_Base::bind_raster_capabilities(
renderive::scene::detail::Raster_Capabilities& capabilities) noexcept {
renderive::scene::detail::Raster_Capabilities& capabilities) {
if (raster_capabilities_ != nullptr)
std::terminate();
renderive::error::unexpected<std::logic_error>("scene raster capabilities are already bound");
raster_capabilities_ = &capabilities;
}
@@ -320,7 +320,7 @@ private:
[[nodiscard]] Scene_Edit_Error validate_structure_locked() const;
[[nodiscard]] Scene_Edit_Error cleanup_detached_topology_locked();
void bind_raster_capabilities(
renderive::scene::detail::Raster_Capabilities& capabilities) noexcept;
renderive::scene::detail::Raster_Capabilities& capabilities);
inline static thread_local Scene_Base* active_execution_scene_{};
inline static thread_local Scene_Base* active_renderable_edit_scene_{};