From 10da16051c6ef9279c04fb299722576c021dde89 Mon Sep 17 00:00:00 2001 From: King_DuckZ Date: Tue, 16 May 2017 18:54:00 +0100 Subject: [PATCH] Organize exceptions so it's easy to log errors locally. --- src/tawashi_implem/CMakeLists.txt | 1 + src/tawashi_implem/error_reasons.hpp | 3 +- src/tawashi_implem/error_response.cpp | 3 +- src/tawashi_implem/submit_paste_response.cpp | 32 ++++++++++------- src/tawashi_implem/submit_paste_response.hpp | 2 -- src/tawashi_implem/tawashi_exception.cpp | 37 ++++++++++++++++++++ src/tawashi_implem/tawashi_exception.hpp | 35 ++++++++++++++++++ 7 files changed, 97 insertions(+), 16 deletions(-) create mode 100644 src/tawashi_implem/tawashi_exception.cpp create mode 100644 src/tawashi_implem/tawashi_exception.hpp diff --git a/src/tawashi_implem/CMakeLists.txt b/src/tawashi_implem/CMakeLists.txt index 38c4283..8b73ebf 100644 --- a/src/tawashi_implem/CMakeLists.txt +++ b/src/tawashi_implem/CMakeLists.txt @@ -25,6 +25,7 @@ add_library(${PROJECT_NAME} STATIC sanitized_utf8.cpp tiger.c error_response.cpp + tawashi_exception.cpp ) target_include_directories(${PROJECT_NAME} diff --git a/src/tawashi_implem/error_reasons.hpp b/src/tawashi_implem/error_reasons.hpp index 98fbb24..1e48505 100644 --- a/src/tawashi_implem/error_reasons.hpp +++ b/src/tawashi_implem/error_reasons.hpp @@ -25,6 +25,7 @@ namespace tawashi { PastieNotSaved, UserFlooding, UnkownReason, - RedisDisconnected + RedisDisconnected, + MissingPostVariable ) } //namespace tawashi diff --git a/src/tawashi_implem/error_response.cpp b/src/tawashi_implem/error_response.cpp index 3263001..45570aa 100644 --- a/src/tawashi_implem/error_response.cpp +++ b/src/tawashi_implem/error_response.cpp @@ -49,7 +49,8 @@ namespace tawashi { "Submitted pastie couldn't be saved.", "The pastie was not saved because the client is submitting too many pasties too quickly. Please wait a bit longer and try again.", "An unknown error was raised.", - "Unable to connect to Redis." + "Unable to connect to Redis.", + "Request is missing a POST variable." }; constexpr const auto lengths = string_lengths(err_descs); static_assert(err_descs.static_size == lengths.static_size, "Mismatching array sizes between strings and their lengths"); diff --git a/src/tawashi_implem/submit_paste_response.cpp b/src/tawashi_implem/submit_paste_response.cpp index 10eae7c..d792900 100644 --- a/src/tawashi_implem/submit_paste_response.cpp +++ b/src/tawashi_implem/submit_paste_response.cpp @@ -24,9 +24,8 @@ #include "duckhandy/compatibility.h" #include "duckhandy/lexical_cast.hpp" #include "duckhandy/int_to_string_ary.hpp" +#include "tawashi_exception.hpp" #include -#include -#include #include #include #include @@ -40,9 +39,14 @@ namespace tawashi { const char g_language_key[] = "lang"; const char g_duration_key[] = "ttl"; - class MissingPostVarError : public std::runtime_error { + class MissingPostVarError : public TawashiException { public: - MissingPostVarError (const std::string& parMsg) : std::runtime_error(parMsg) {} + explicit MissingPostVarError(const boost::string_ref& parKey) : + TawashiException( + ErrorReasons::MissingPostVariable, + "Error retrieving POST variable \"" + std::string(parKey.begin(), parKey.end()) + "\"" + ) + {} }; template @@ -57,11 +61,8 @@ namespace tawashi { boost::string_ref get_value_from_post (const cgi::PostMapType& parPost, boost::string_ref parKey) { std::string key(parKey.data(), parKey.size()); auto post_data_it = parPost.find(key); - if (parPost.end() == post_data_it) { - std::ostringstream oss; - oss << "can't find POST data field \"" << parKey << '"'; - throw MissingPostVarError(oss.str()); - } + if (parPost.end() == post_data_it) + throw MissingPostVarError(parKey); return post_data_it->second; } @@ -104,18 +105,24 @@ namespace tawashi { boost::string_ref pastie; boost::string_ref lang; boost::string_ref duration; + + auto statuslog = spdlog::get("statuslog"); + assert(statuslog); + try { pastie = get_value_from_post(post, make_string_ref(g_post_key)); } - catch (const MissingPostVarError& e) { - m_error_message = e.what(); + catch (const TawashiException& e) { + statuslog->error(e.what()); + error_redirect(500, e.reason()); return; } try { lang = get_value_from_post(post, make_string_ref(g_language_key)); duration = get_value_from_post(post, make_string_ref(g_duration_key)); } - catch (const MissingPostVarError&) { + catch (const MissingPostVarError& e) { + statuslog->info(e.what()); } const SettingsBag& settings = this->settings(); @@ -145,6 +152,7 @@ namespace tawashi { this->change_type(Response::Location, oss.str()); } else { + error_redirect(500, ErrorReasons::PastieNotSaved); return; } } diff --git a/src/tawashi_implem/submit_paste_response.hpp b/src/tawashi_implem/submit_paste_response.hpp index bf53ffa..253ecc7 100644 --- a/src/tawashi_implem/submit_paste_response.hpp +++ b/src/tawashi_implem/submit_paste_response.hpp @@ -39,7 +39,5 @@ namespace tawashi { virtual void on_process() override; boost::optional submit_to_redis (const boost::string_ref& parText, uint32_t parExpiry, const boost::string_ref& parLang); void error_redirect (int parCode, ErrorReasons parReason); - - std::string m_error_message; }; } //namespace tawashi diff --git a/src/tawashi_implem/tawashi_exception.cpp b/src/tawashi_implem/tawashi_exception.cpp new file mode 100644 index 0000000..f572f59 --- /dev/null +++ b/src/tawashi_implem/tawashi_exception.cpp @@ -0,0 +1,37 @@ +/* Copyright 2017, Michele Santullo + * This file is part of "tawashi". + * + * "tawashi" is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * "tawashi" is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with "tawashi". If not, see . + */ + +#include "tawashi_exception.hpp" +#include + +namespace tawashi { + namespace { + std::string compose_err_message (ErrorReasons parReason, const boost::string_ref& parMessage) { + std::ostringstream oss; + oss << "Exception with reason " << parReason << ": " << parMessage; + return oss.str(); + } + } //unnamed namespace + + TawashiException::TawashiException (ErrorReasons parReason, const boost::string_ref& parMessage) : + std::runtime_error(compose_err_message(parReason, parMessage)), + m_reason(parReason) + { + } + + TawashiException::~TawashiException() noexcept = default; +} //namespace tawashi diff --git a/src/tawashi_implem/tawashi_exception.hpp b/src/tawashi_implem/tawashi_exception.hpp new file mode 100644 index 0000000..fae9634 --- /dev/null +++ b/src/tawashi_implem/tawashi_exception.hpp @@ -0,0 +1,35 @@ +/* Copyright 2017, Michele Santullo + * This file is part of "tawashi". + * + * "tawashi" is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * "tawashi" is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with "tawashi". If not, see . + */ + +#pragma once +#include "error_reasons.hpp" +#include +#include +#include + +namespace tawashi { + class TawashiException : public std::runtime_error { + public: + TawashiException (ErrorReasons parReason, const boost::string_ref& parMessage); + ~TawashiException() noexcept; + + ErrorReasons reason() const { return m_reason; } + + private: + ErrorReasons m_reason; + }; +} //namespace tawashi