srctree

Robin Linden parent 1057585e 4357ee7d
http: Replace logging with error codes

This means fewer dependencies in core libraries and that applicationscan choose how to handle and display the different errors themselves.

inlinesplit
browser/BUILD added: 46, removed: 20, total 26
@@ -30,5 +30,6 @@ cc_binary(
"@imgui",
"@imgui-sfml",
"@sfml//:graphics",
"@spdlog",
],
)
 
browser/gui.cpp added: 46, removed: 20, total 26
@@ -1,11 +1,13 @@
#include "http/get.h"
#include "html/parse.h"
 
#include <fmt/format.h>
#include <imgui.h>
#include <imgui-SFML.h>
#include <SFML/Graphics/RenderWindow.hpp>
#include <SFML/System/Clock.hpp>
#include <SFML/Window/Event.hpp>
#include <spdlog/spdlog.h>
 
int main() {
sf::RenderWindow window{sf::VideoMode(640, 480), "gui"};
@@ -17,6 +19,7 @@ int main() {
http::Response response{};
std::vector<dom::Node> dom{};
std::string dom_str{};
std::string err_str{};
 
while (window.isOpen()) {
sf::Event event;
@@ -34,13 +37,32 @@ int main() {
if (ImGui::InputText(
"Url", url_buf, sizeof(url_buf), ImGuiInputTextFlags_EnterReturnsTrue)) {
response = http::get(url_buf);
dom = html::parse(response.body);
dom_str.clear();
for (const auto &node : dom) {
dom_str += dom::to_string(node);
dom_str += '\n';
 
switch (response.err) {
case http::Error::Ok: {
dom = html::parse(response.body);
for (const auto &node : dom) {
dom_str += dom::to_string(node);
dom_str += '\n';
}
break;
}
case http::Error::Unresolved: {
err_str = fmt::format("Unable to resolve endpoint for '{}'", url_buf);
spdlog::error(err_str);
break;
}
case http::Error::Unhandled: {
err_str = fmt::format("Unhandled protocol for '{}'", url_buf);
spdlog::error(err_str);
break;
}
}
}
if (response.err != http::Error::Ok) {
ImGui::Text("%s", err_str.c_str());
}
ImGui::End();
 
ImGui::Begin("HTTP Response");
 
browser/tui.cpp added: 46, removed: 20, total 26
@@ -15,8 +15,8 @@ int main(int argc, char **argv) {
 
spdlog::info("Fetching HTML from {}", endpoint);
auto response = http::get(endpoint);
if (response.header.empty() || response.body.empty()) {
spdlog::error("Got no response from {}", endpoint);
if (response.err != http::Error::Ok) {
spdlog::error("Got error {} from {}", response.err, endpoint);
return 1;
}
 
 
http/BUILD added: 46, removed: 20, total 26
@@ -8,6 +8,5 @@ cc_library(
deps = [
"@asio",
"@fmt",
"@spdlog",
],
)
 
http/get.cpp added: 46, removed: 20, total 26
@@ -3,7 +3,6 @@
#include <asio.hpp>
#include <asio/ssl.hpp>
#include <fmt/format.h>
#include <spdlog/spdlog.h>
 
#include <sstream>
#include <string>
@@ -45,7 +44,7 @@ Response get(std::string_view url) {
std::string data{ss.str()};
 
auto [header, body] = split(data, "\r\n\r\n");
return {std::string{header}, std::string{body}};
return {Error::Ok, std::string{header}, std::string{body}};
}
 
if (protocol == "https"sv) {
@@ -57,8 +56,7 @@ Response get(std::string_view url) {
asio::ip::tcp::resolver resolver{svc};
auto endpoints = resolver.resolve(endpoint, "https"sv, ec);
if (ec) {
spdlog::error("http::get: Unable to resolve https endpoint '{}'", endpoint);
return {};
return {Error::Unresolved};
}
 
ssock.lowest_layer().connect(*endpoints.begin());
@@ -80,11 +78,10 @@ Response get(std::string_view url) {
}
 
auto [header, body] = split(data, "\r\n\r\n");
return {std::string{header}, std::string{body}};
return {Error::Ok, std::string{header}, std::string{body}};
}
 
spdlog::error("http::get: Unhandled protocol '{}'", protocol);
return {};
return {Error::Unhandled};
}
 
} // namespace http
 
http/get.h added: 46, removed: 20, total 26
@@ -6,7 +6,14 @@
 
namespace http {
 
enum class Error {
Ok,
Unresolved,
Unhandled,
};
 
struct Response {
Error err;
std::string header;
std::string body;
};