aboutsummaryrefslogtreecommitdiff
path: root/include/ricochet/net/sys/exception.hh
diff options
context:
space:
mode:
authorRichard Qin <richard.qin.x@gmail.com>2026-04-11 02:20:31 +0800
committerRichard Qin <richard.qin.x@gmail.com>2026-04-11 02:20:31 +0800
commit98e88c01eb0e6404d1c5f49a22165d0861e6b924 (patch)
treed016d445fe476f747eea9030896214adeaacf51f /include/ricochet/net/sys/exception.hh
parent44ad3c8b36540c6b0b3144a21ac40310e163bb19 (diff)
downloadrwebbrowser-98e88c01eb0e6404d1c5f49a22165d0861e6b924.tar.gz
rwebbrowser-98e88c01eb0e6404d1c5f49a22165d0861e6b924.tar.xz
feat: implement basic HTTP client with socket and address networking utilities
Diffstat (limited to 'include/ricochet/net/sys/exception.hh')
-rw-r--r--include/ricochet/net/sys/exception.hh80
1 files changed, 80 insertions, 0 deletions
diff --git a/include/ricochet/net/sys/exception.hh b/include/ricochet/net/sys/exception.hh
new file mode 100644
index 0000000..9587e5c
--- /dev/null
+++ b/include/ricochet/net/sys/exception.hh
@@ -0,0 +1,80 @@
+/**
+ * ---------------------------------------------------------------------------
+ * @notice This file was adapted from the Minnow networking framework,
+ * originally developed for Stanford University's CS144 course.
+ * It has been incorporated into the Ricochet project as foundational
+ * system utility code.
+ * ---------------------------------------------------------------------------
+ */
+
+#pragma once
+
+#include <cxxabi.h>
+#include <memory>
+#include <string>
+#include <string_view>
+#include <system_error>
+
+class tagged_error : public std::system_error
+{
+private:
+ std::string attempt_and_error_;
+ int error_code_;
+
+public:
+ tagged_error( const std::error_category& category, const std::string_view s_attempt, const int error_code )
+ : system_error( error_code, category )
+ , attempt_and_error_( std::string( s_attempt ) + ": " + std::system_error::what() )
+ , error_code_( error_code )
+ {}
+
+ const char* what() const noexcept override { return attempt_and_error_.c_str(); }
+
+ int error_code() const { return error_code_; }
+};
+
+class unix_error : public tagged_error
+{
+public:
+ explicit unix_error( const std::string_view s_attempt, const int s_errno = errno )
+ : tagged_error( std::system_category(), s_attempt, s_errno )
+ {}
+};
+
+inline int CheckSystemCall( const std::string_view s_attempt, const int return_value )
+{
+ if ( return_value >= 0 ) {
+ return return_value;
+ }
+
+ throw unix_error { s_attempt };
+}
+
+template<typename T>
+inline T* notnull( const std::string_view context, T* const x )
+{
+ return x ? x : throw std::runtime_error( std::string( context ) + ": returned null pointer" );
+}
+
+template<typename T>
+inline std::unique_ptr<T> notnull( const std::string_view context, std::unique_ptr<T> x )
+{
+ return x ? x : throw std::runtime_error( std::string( context ) + ": returned null pointer" );
+}
+
+template<typename T>
+inline std::shared_ptr<T> notnull( const std::string_view context, std::shared_ptr<T>&& x )
+{
+ return x ? std::move( x ) : throw std::runtime_error( std::string( context ) + ": returned null pointer" );
+}
+
+inline std::string demangle( const char* name )
+{
+ int status {};
+ const std::unique_ptr<char, decltype( &free )> res { abi::__cxa_demangle( name, nullptr, nullptr, &status ),
+ free };
+ if ( status ) {
+ throw std::runtime_error( "cxa_demangle" );
+ }
+ return res.get();
+}