/* Copyright © 2005-2007 Roger Leigh * * schroot 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. * * schroot 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 this program. If not, see * . * *********************************************************************/ #ifndef SBUILD_ERROR_H #define SBUILD_ERROR_H #include #include #include #include #include #include namespace sbuild { /** * Error exception base class. */ class error_base : public std::runtime_error { protected: /** * The constructor. * * @param error the error message. */ error_base(std::string const& error): runtime_error(error), reason() { } /** * The constructor. * * @param error the error message. * @param reason further information about the error */ error_base(std::string const& error, std::string const& reason): runtime_error(error), reason(reason) { } public: /// The destructor. virtual ~error_base () throw () {} /** * Get the reason for the error. * * @returns the reason. */ virtual const char * why () const throw () { return this->reason.c_str(); } /** * Get the reason for the error. * * @returns the reason. */ std::string const& get_reason () const { return this->reason; } /** * Set the reason for the error. * * @param reason further information about the error */ void set_reason (std::string const& reason) { this->reason = reason; } private: /// The reason for the error. std::string reason; }; /** * Error exception class. */ template class error : public error_base { public: /// The enum type providing the error codes for this type. typedef T error_type; /// Mapping between error code and error description. typedef std::map map_type; /** * The constructor. * * @param error the error message. */ error(std::string const& error): error_base(error) { } /** * The constructor. * * @param error the error message. * @param reason further information about the error */ error(std::string const& error, std::string const& reason): error_base(error, reason) { } /// The destructor. virtual ~error () throw () {} private: /// Mapping between error code and string. static map_type error_strings; /** * Get a translated error string. * * @param error the error code. * @returns a translated error string. */ static const char * get_error (error_type error); protected: /** * Format an error message. * * @param context1 context of the error. * @param context2 additional context of the error. * @param context3 additional context of the error. * @param error the error code. * @param detail1 details of the error. * @param detail2 additional details of the error. * @param detail3 additional details of the error. * @returns a translated error message. * * @todo Merge the logic shared between the two specialisations to * prevent code duplication. */ template static std::string format_error (A const& context1, B const& context2, C const& context3, error_type error, D const& detail1, E const& detail2, F const& detail3); /** * Format an error message. * * @param context1 context of the error. * @param context2 additional context of the error. * @param context3 additional context of the error. * @param error the error code. * @param detail1 details of the error. * @param detail2 additional details of the error. * @param detail3 additional details of the error. * @returns a translated error message. */ template static std::string format_error (A const& context1, B const& context2, C const& context3, std::runtime_error const& error, D const& detail1, E const& detail2, F const& detail3); /** * Format an reason string. * * @param context1 context of the error. * @param context2 additional context of the error. * @param context3 additional context of the error. * @param error the error or error code. * @param detail1 details of the error. * @param detail2 additional details of the error. * @param detail3 additional details of the error. * @returns a translated error message. */ template static std::string format_reason (A const& context1, B const& context2, C const& context3, R const& error, D const& detail1, E const& detail2, F const& detail3); /** * Add detail to format string. * * @param fmt the format string. * @param value the value to add. */ template static void add_detail(boost::format& fmt, A const& value); /** * Helper class to add detail to format string. * Used for non-exception types. */ template struct add_detail_helper { /** * The constructor. * * @param fmt the format string to add to. * @param value the value to add. */ add_detail_helper(boost::format& fmt, A const& value) { fmt % value; } }; /** * Helper class to add detail to format string. * Used for exception types. */ template struct add_detail_helper { /** * The constructor. * * @param fmt the format string to add to. * @param value the exception to add. */ add_detail_helper(boost::format& fmt, A const& value) { fmt % value.what(); } }; /** * Add reason to reason string. * * @param reason the reason string. * @param value the value to add. */ template static void add_reason(std::string& reason, A const& value); /** * Helper class to add reason to reason string. * Used for non-exception types. */ template struct add_reason_helper { /** * The constructor. * * @param reason the reason to add to. * @param value the value to add. */ add_reason_helper(std::string& reason, A const& value) { } }; /** * Helper class to add reason to reason string. * Used for exception types. */ template struct add_reason_helper { /** * The constructor. * * @param reason the reason to add to. * @param value the exception to add. */ add_reason_helper(std::string& reason, A const& value) { try { sbuild::error_base const& eb(dynamic_cast(value)); if (!reason.empty()) reason += '\n'; reason += eb.why(); } catch (std::bad_cast const& discard) { } } }; }; } #include "sbuild-error.tcc" #endif /* SBUILD_ERROR_H */ /* * Local Variables: * mode:C++ * End: */