Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions include/netkit/body/read_status_enum.hpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#pragma once

#include <netkit/export.hpp>
#include <netkit/except.hpp>
#include <netkit/io/task.hpp>

#include <string>
Expand Down Expand Up @@ -65,7 +66,7 @@ namespace netkit::body {
auto res = reader.read(buffer, sizeof(buffer));

if (res.get_status() == read_status::error)
throw std::runtime_error("read failed");
throw netkit::io_error("read failed");

if (res.get_status() == read_status::timeout)
continue;
Expand Down Expand Up @@ -96,7 +97,7 @@ namespace netkit::body {
auto res = co_await reader.read(buffer, sizeof(buffer));

if (res.get_status() == read_status::error)
throw std::runtime_error("read failed");
throw netkit::io_error("read failed");

if (res.get_status() == read_status::timeout)
continue;
Expand Down
41 changes: 39 additions & 2 deletions include/netkit/except.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
*/
#pragma once

#include <exception>
#include <string>
#include <utility>

Expand Down Expand Up @@ -51,11 +52,47 @@ namespace netkit {
explicit dns_error(std::string msg) : generic_error(std::move(msg)) {}
};

#ifdef NETKIT_OPENSSL
/**
* @brief Thrown for TLS/SSL failures (handshake, context/session setup, certificate export, etc.).
* @note Not guarded behind a TLS backend macro: the class itself has no backend dependency,
* only the code paths that throw it (e.g. src/stream/wolfssl/*, src/stream/openssl/*) do.
*/
class NETKIT_API ssl_error : public generic_error {
public:
ssl_error() : generic_error("SSL error") {}
explicit ssl_error(std::string msg) : generic_error(std::move(msg)) {}
};
#endif

/**
* @brief Thrown when netkit is used incorrectly: an object is used in an invalid state,
* a precondition/argument is violated, or an operation is not supported.
* @note Mirrors the role std::logic_error plays in the standard library, but lives in
* netkit's own hierarchy so callers only ever need to catch netkit::generic_error.
*/
class NETKIT_API logic_error : public generic_error {
public:
logic_error() : generic_error("Logic error") {}
explicit logic_error(std::string msg) : generic_error(std::move(msg)) {}
};

/**
* @brief Thrown when an operation would exceed (or exceeded) an explicit size/length bound.
* @note Mirrors std::length_error, and like it, derives from the "logic error" branch of
* the hierarchy since exceeding a caller-specified bound is a precondition violation.
*/
class NETKIT_API length_error : public logic_error {
public:
length_error() : logic_error("Length error") {}
explicit length_error(std::string msg) : logic_error(std::move(msg)) {}
};

/**
* @brief Thrown for low-level I/O failures that aren't specific to a socket, IP, or DNS
* operation: file access, and OS event-loop backends (epoll/kqueue/IOCP/etc.).
*/
class NETKIT_API io_error : public generic_error {
public:
io_error() : generic_error("I/O error") {}
explicit io_error(std::string msg) : generic_error(std::move(msg)) {}
};
}
7 changes: 4 additions & 3 deletions include/netkit/http/async_client.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include <string>

#include <netkit/export.hpp>
#include <netkit/except.hpp>
#include <netkit/http/predefined.hpp>
#include <netkit/socket/addr.hpp>

Expand Down Expand Up @@ -113,11 +114,11 @@ namespace netkit::http {
ss << method;

if (path.empty()) {
throw std::logic_error("path is empty");
throw netkit::logic_error("path is empty");
}

if (path.at(0) != '/') {
throw std::logic_error("path must start with /");
throw netkit::logic_error("path must start with /");
}

ss << " " << path << " HTTP/1.1" << "\r\n";
Expand Down Expand Up @@ -145,7 +146,7 @@ namespace netkit::http {
const auto line_end = header_data.find_first_of("\r\n");

if (line_end == std::string::npos)
throw std::logic_error{"invalid HTTP async_response"};
throw netkit::parsing_error{"invalid HTTP async_response"};

const auto status_line = std::string_view{
header_data.data(),
Expand Down
5 changes: 3 additions & 2 deletions include/netkit/http/basic_request_handler.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#ifdef NETKIT_HTTP

#include <netkit/tcp/tcp_stream.hpp>
#include <netkit/except.hpp>
#include <netkit/tcp/async_tcp_stream.hpp>
#include <netkit/http/server_predefined.hpp>

Expand All @@ -22,10 +23,10 @@ namespace netkit::http::server {
class basic_request_handler {
public:
virtual void handle(std::unique_ptr<tcp::tcp_stream>, server_settings&, const request_callback&) const {
throw std::runtime_error("not implemented");
throw netkit::logic_error("not implemented");
}
virtual io::task<void> handle(std::unique_ptr<tcp::async_tcp_stream>, server_settings&, const async_request_callback&) const {
throw std::runtime_error("not implemented");
throw netkit::logic_error("not implemented");
}
virtual ~basic_request_handler() = default;
};
Expand Down
7 changes: 4 additions & 3 deletions include/netkit/http/client.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include <vector>

#include <netkit/export.hpp>
#include <netkit/except.hpp>
#include <netkit/http/predefined.hpp>
#include <netkit/body/basic_body.hpp>
#include <netkit/socket/addr.hpp>
Expand Down Expand Up @@ -108,11 +109,11 @@ namespace netkit::http {
ss << method;

if (path.empty()) {
throw std::logic_error("path is empty");
throw netkit::logic_error("path is empty");
}

if (path.at(0) != '/') {
throw std::logic_error("path must start with /");
throw netkit::logic_error("path must start with /");
}

ss << " " << path << " HTTP/1.1" << "\r\n";
Expand Down Expand Up @@ -140,7 +141,7 @@ namespace netkit::http {
const auto line_end = header_data.find_first_of("\r\n");

if (line_end == std::string::npos)
throw std::logic_error{"invalid HTTP response"};
throw netkit::parsing_error{"invalid HTTP response"};

const auto status_line = std::string_view{
header_data.data(),
Expand Down
7 changes: 4 additions & 3 deletions include/netkit/http/header.hpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#pragma once

#include <netkit/export.hpp>
#include <netkit/except.hpp>
#include <string>
#include <string_view>
#include <vector>
Expand Down Expand Up @@ -230,13 +231,13 @@ namespace netkit::http {
const auto first_space = status_line.find(' ');

if (first_space == std::string_view::npos)
throw std::logic_error{"invalid HTTP status line"};
throw netkit::parsing_error{"invalid HTTP status line"};

const auto code_start = first_space + 1;
const auto second_space = status_line.find(' ', code_start);

if (second_space == std::string_view::npos)
throw std::logic_error{"invalid HTTP status line"};
throw netkit::parsing_error{"invalid HTTP status line"};

const auto code_str = status_line.substr(
code_start,
Expand All @@ -248,7 +249,7 @@ namespace netkit::http {
const auto [ptr, ec] = std::from_chars(code_str.data(), code_str.data() + code_str.size(), code);

if (ec != std::errc{} || ptr != code_str.data() + code_str.size())
throw std::logic_error{"invalid HTTP status code"};
throw netkit::parsing_error{"invalid HTTP status code"};

return code;
}
Expand Down
12 changes: 6 additions & 6 deletions include/netkit/http/request_handler.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ namespace netkit::http::server {
}

if (!file.is_open()) {
throw std::runtime_error("failed to open session file (read_from_session_file()): " + f);
throw netkit::io_error("failed to open session file (read_from_session_file()): " + f);
}

std::string line{};
Expand All @@ -91,7 +91,7 @@ namespace netkit::http::server {
std::ofstream file(f, std::ios::trunc);

if (!file.is_open() || !file.good()) {
throw std::runtime_error("failed to open session file (write_to_session_file()): " + f);
throw netkit::io_error("failed to open session file (write_to_session_file()): " + f);
}

for (const auto& it : session) {
Expand Down Expand Up @@ -467,7 +467,7 @@ namespace netkit::http::server {

switch (result.get_status()) {
case status_t::error:
throw std::runtime_error("Body read error");
throw netkit::io_error("Body read error");

case status_t::timeout:
continue;
Expand All @@ -487,7 +487,7 @@ namespace netkit::http::server {
));

if (write_status == netkit::stream::stream_status::error)
throw std::runtime_error("Socket write error");
throw netkit::socket_error("Socket write error");

total_sent += sent;
}
Expand Down Expand Up @@ -788,7 +788,7 @@ namespace netkit::http::server {

switch (result.get_status()) {
case status_t::error:
throw std::runtime_error("Body read error");
throw netkit::io_error("Body read error");

case status_t::timeout:
continue;
Expand All @@ -808,7 +808,7 @@ namespace netkit::http::server {
));

if (write_status == netkit::stream::stream_status::error)
throw std::runtime_error("Socket write error");
throw netkit::socket_error("Socket write error");

total_sent += sent;
}
Expand Down
5 changes: 3 additions & 2 deletions include/netkit/io/cancellation.hpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#pragma once

#include <netkit/export.hpp>
#include <netkit/except.hpp>
#include <atomic>
#include <memory>
#include <coroutine>
Expand All @@ -10,9 +11,9 @@ namespace netkit::io {
/**
* @brief Exception thrown when a task is cancelled.
*/
class NETKIT_API cancelled_error : public std::runtime_error {
class NETKIT_API cancelled_error : public netkit::generic_error {
public:
cancelled_error() : std::runtime_error("Task was cancelled") {}
cancelled_error() : netkit::generic_error("Task was cancelled") {}
};

/**
Expand Down
5 changes: 3 additions & 2 deletions include/netkit/io/timeout.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include <functional>
#include <memory>
#include <netkit/export.hpp>
#include <netkit/except.hpp>
#include <netkit/io/cancellation.hpp>
#include <netkit/io/task.hpp>
#include <thread>
Expand All @@ -13,9 +14,9 @@ namespace netkit::io {
/**
* @brief Exception thrown when an operation times out.
*/
class NETKIT_API timeout_error : public std::runtime_error {
class NETKIT_API timeout_error : public netkit::generic_error {
public:
timeout_error() : std::runtime_error("Operation timed out") {}
timeout_error() : netkit::generic_error("Operation timed out") {}
};

/**
Expand Down
5 changes: 3 additions & 2 deletions include/netkit/socket/native/basic_native_async_listener.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

#include <memory>
#include <netkit/io/io_context.hpp>
#include <netkit/except.hpp>
#include <netkit/socket/addr.hpp>
#include <netkit/socket/addr_type.hpp>
#include <netkit/socket/native/basic_native_async_socket.hpp>
Expand All @@ -19,10 +20,10 @@ namespace netkit::socket::native {
virtual void close() noexcept = 0;

[[nodiscard]] virtual const addr& get_local_endpoint() const {
throw std::logic_error{"socket does not have an addr object"};
throw netkit::logic_error{"socket does not have an addr object"};
}
[[nodiscard]] virtual fd_t native_handle() const {
throw std::logic_error{"socket does not have a native handle"};
throw netkit::logic_error{"socket does not have a native handle"};
}
};
}
13 changes: 7 additions & 6 deletions include/netkit/socket/native/basic_native_async_socket.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

#include <memory>
#include <netkit/io/io_context.hpp>
#include <netkit/except.hpp>
#include <netkit/socket/addr.hpp>
#include <netkit/socket/addr_type.hpp>

Expand All @@ -38,22 +39,22 @@ namespace netkit::socket::native {
virtual void unbind() noexcept = 0;

virtual addr& get_addr() {
throw std::logic_error{"socket does not have an addr object"};
throw netkit::logic_error{"socket does not have an addr object"};
}
[[nodiscard]] virtual const addr& get_addr() const {
throw std::logic_error{"socket does not have an addr object"};
throw netkit::logic_error{"socket does not have an addr object"};
}
[[nodiscard]] virtual addr get_peer() const {
throw std::logic_error{"socket does not have a peer"};
throw netkit::logic_error{"socket does not have a peer"};
};
virtual void set_sock_opts(opt opts) {
throw std::logic_error{"socket does not have opts to set"};
throw netkit::logic_error{"socket does not have opts to set"};
}
[[nodiscard]] virtual fd_t native_handle() const {
throw std::logic_error{"socket does not have a native handle"};
throw netkit::logic_error{"socket does not have a native handle"};
}
[[nodiscard]] virtual io::io_context& native_io_context() {
throw std::logic_error{"socket does not have an io context"};
throw netkit::logic_error{"socket does not have an io context"};
}
};
}
5 changes: 3 additions & 2 deletions include/netkit/socket/native/basic_native_sync_listener.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

#include <memory>
#include <netkit/socket/addr.hpp>
#include <netkit/except.hpp>
#include <netkit/socket/addr_type.hpp>

namespace netkit::socket::native {
Expand All @@ -21,12 +22,12 @@ namespace netkit::socket::native {
[[nodiscard]] virtual std::unique_ptr<basic_native_sync_socket> accept() = 0;

[[nodiscard]] virtual const addr& get_local_endpoint() const {
throw std::logic_error{"socket does not have an addr object"};
throw netkit::logic_error{"socket does not have an addr object"};
}
virtual void close() noexcept = 0;

[[nodiscard]] virtual fd_t native_handle() const {
throw std::logic_error{"socket does not have a native handle"};
throw netkit::logic_error{"socket does not have a native handle"};
}
};
}
Loading
Loading