transition to system_error as the exception type (#730)

transition to system_error as the exception type
This commit is contained in:
Arvid Norberg 2016-05-15 00:33:06 -04:00
parent 0d27a0acdd
commit 1e7e01c671
19 changed files with 77 additions and 122 deletions

View File

@ -1,3 +1,4 @@
* transitioned exception types to system_error
* made alerts move-only
* move files one-by-one when moving storage for a torrent
* removed RSS support
@ -12,6 +13,7 @@
* deprecated ssl_listen, SSL sockets are specified in listen_interfaces now
* improved support for listening on multiple sockets and interfaces
* resume data no longer has timestamps of files
* require C++11 to build libtorrent
1.1.1 release

View File

@ -42,7 +42,7 @@ namespace {
error_code ec;
parse_magnet_uri(uri, p, ec);
if (ec) throw libtorrent_exception(ec);
if (ec) throw system_error(ec);
dict ret;

View File

@ -46,7 +46,7 @@ namespace
error_code ec;
s.listen_on(std::make_pair(min_, max_), ec, interface, flags);
#ifndef BOOST_NO_EXCEPTIONS
if (ec) throw libtorrent_exception(ec);
if (ec) throw system_error(ec);
#endif
}
#endif
@ -472,7 +472,7 @@ namespace
error_code ec;
add_torrent_params p = read_resume_data(&b.arr[0], b.arr.size(), ec);
#ifndef BOOST_NO_EXCEPTIONS
if (ec) throw libtorrent_exception(ec);
if (ec) throw system_error(ec);
#endif
return p;
}

View File

@ -142,7 +142,7 @@ boost::shared_ptr<torrent_info> buffer_constructor0(char const* buf, int len, in
boost::shared_ptr<torrent_info> ret(boost::make_shared<torrent_info>(buf
, len, boost::ref(ec), flags));
#ifndef BOOST_NO_EXCEPTIONS
if (ec) throw libtorrent_exception(ec);
if (ec) throw system_error(ec);
#endif
return ret;
}
@ -158,7 +158,7 @@ boost::shared_ptr<torrent_info> file_constructor0(std::string const& filename, i
boost::shared_ptr<torrent_info> ret(boost::make_shared<torrent_info>(filename
, boost::ref(ec), flags));
#ifndef BOOST_NO_EXCEPTIONS
if (ec) throw libtorrent_exception(ec);
if (ec) throw system_error(ec);
#endif
return ret;
}
@ -178,14 +178,14 @@ boost::shared_ptr<torrent_info> bencoded_constructor0(entry const& ent, int flag
if (buf.size() == 0 || bdecode(&buf[0], &buf[0] + buf.size(), e, ec) != 0)
{
#ifndef BOOST_NO_EXCEPTIONS
throw invalid_torrent_file(ec);
throw system_error(ec);
#endif
}
boost::shared_ptr<torrent_info> ret(boost::make_shared<torrent_info>(e
, boost::ref(ec), flags));
#ifndef BOOST_NO_EXCEPTIONS
if (ec) throw libtorrent_exception(ec);
if (ec) throw system_error(ec);
#endif
return ret;
}

View File

@ -106,10 +106,8 @@ Many functions in libtorrent have two versions, one that throws exceptions on
errors and one that takes an ``error_code`` reference which is filled with the
error code on errors.
There is one exception class that is used for errors in libtorrent, it is based
on boost.system's ``error_code`` class to carry the error code.
For more information, see libtorrent_exception and error_code_enum.
On exceptions, libtorrent will throw ``boost::system::system_error`` exceptions
carrying an ``error_code`` describing the underlying error.
translating error codes
-----------------------

View File

@ -92,15 +92,7 @@ namespace libtorrent
{
#ifndef TORRENT_NO_DEPRECATE
// thrown by bdecode() if the provided bencoded buffer does not contain
// valid encoding.
struct invalid_encoding: std::exception
{
// hidden
virtual const char* what() const TORRENT_EXCEPTION_THROW_SPECIFIER
override final
{ return "invalid bencoding"; }
};
using invalid_encoding = system_error;
#endif
namespace detail

View File

@ -419,14 +419,14 @@ namespace libtorrent
{
error_code ec;
set_piece_hashes(t, p, detail::nop, ec);
if (ec) throw libtorrent_exception(ec);
if (ec) throw system_error(ec);
}
template <class Fun>
void set_piece_hashes(create_torrent& t, std::string const& p, Fun f)
{
error_code ec;
set_piece_hashes(t, p, f, ec);
if (ec) throw libtorrent_exception(ec);
if (ec) throw system_error(ec);
}
#endif
@ -462,7 +462,7 @@ namespace libtorrent
{
error_code ec;
set_piece_hashes_deprecated(t, p, f, ec);
if (ec) throw libtorrent_exception(ec);
if (ec) throw system_error(ec);
}
TORRENT_DEPRECATED
@ -471,7 +471,7 @@ namespace libtorrent
{
error_code ec;
set_piece_hashes_deprecated(t, p, detail::nop, ec);
if (ec) throw libtorrent_exception(ec);
if (ec) throw system_error(ec);
}
#endif

View File

@ -82,18 +82,11 @@ namespace libtorrent
{
#ifndef TORRENT_NO_DEPRECATE
struct lazy_entry;
// backwards compatibility
using type_error = system_error;
#endif
struct bdecode_node;
// thrown by any accessor function of entry if the accessor
// function requires a type different than the actual type
// of the entry object.
struct type_error : std::runtime_error
{
// internal
type_error(const char* error): std::runtime_error(error) {}
};
// The ``entry`` class represents one node in a bencoded hierarchy. It works as a
// variant type, it can be either a list, a dictionary (``std::map``), an integer
// or a string.
@ -168,8 +161,8 @@ namespace libtorrent
// The ``integer()``, ``string()``, ``list()`` and ``dict()`` functions
// are accessors that return the respective type. If the ``entry`` object
// isn't of the type you request, the accessor will throw
// libtorrent_exception (which derives from ``std::runtime_error``). You
// can ask an ``entry`` for its type through the ``type()`` function.
// system_error. You can ask an ``entry`` for its type through the
// ``type()`` function.
//
// If you want to create an ``entry`` you give it the type you want it to
// have in its constructor, and then use one of the non-const accessors
@ -227,7 +220,7 @@ namespace libtorrent
void swap(entry& e);
// All of these functions requires the entry to be a dictionary, if it
// isn't they will throw ``libtorrent::type_error``.
// isn't they will throw ``system_error``.
//
// The non-const versions of the ``operator[]`` will return a reference
// to either the existing element at the given key or, if there is no
@ -236,7 +229,7 @@ namespace libtorrent
//
// The const version of ``operator[]`` will only return a reference to an
// existing element at the given key. If the key is not found, it will
// throw ``libtorrent::type_error``.
// throw ``system_error``.
entry& operator[](char const* key);
entry& operator[](std::string const& key);
#ifndef BOOST_NO_EXCEPTIONS
@ -245,7 +238,7 @@ namespace libtorrent
#endif
// These functions requires the entry to be a dictionary, if it isn't
// they will throw ``libtorrent::type_error``.
// they will throw ``system_error``.
//
// They will look for an element at the given key in the dictionary, if
// the element cannot be found, they will return 0. If an element with
@ -321,15 +314,6 @@ namespace libtorrent
}
#endif
#ifndef BOOST_NO_EXCEPTIONS
// internal
TORRENT_NO_RETURN inline void throw_type_error()
{
throw libtorrent_exception(error_code(errors::invalid_entry_type
, get_libtorrent_category()));
}
#endif
}
#endif // TORRENT_ENTRY_HPP_INCLUDED

View File

@ -36,7 +36,6 @@ POSSIBILITY OF SUCH DAMAGE.
#include <boost/version.hpp>
#include "libtorrent/config.hpp"
#include "libtorrent/string_util.hpp" // for allocate_string_copy
#include <stdlib.h> // free
#include "libtorrent/aux_/disable_warnings_push.hpp"
@ -46,6 +45,7 @@ POSSIBILITY OF SUCH DAMAGE.
#endif
#include <boost/system/error_code.hpp>
#include <boost/system/system_error.hpp>
#include <boost/asio/error.hpp>
#include "libtorrent/aux_/disable_warnings_pop.hpp"
@ -489,20 +489,11 @@ namespace libtorrent
using boost::system::system_category;
#ifndef BOOST_NO_EXCEPTIONS
struct TORRENT_EXPORT libtorrent_exception: std::exception
{
libtorrent_exception(error_code const& s): m_error(s), m_msg(0) {}
virtual const char* what() const TORRENT_EXCEPTION_THROW_SPECIFIER;
virtual ~libtorrent_exception() TORRENT_EXCEPTION_THROW_SPECIFIER;
#if __cplusplus >= 201103L
libtorrent_exception(libtorrent_exception const&) = default;
libtorrent_exception& operator=(libtorrent_exception const&) = default;
using boost::system::system_error;
#ifndef TORRENT_NO_DEPRECATE
using system_error = boost::system::system_error;
#endif
error_code error() const { return m_error; }
private:
error_code m_error;
mutable char* m_msg;
};
#endif
// used by storage to return errors

View File

@ -200,7 +200,7 @@ namespace libtorrent
//
// If the torrent you are trying to add already exists in the session (is
// either queued for checking, being checked or downloading)
// ``add_torrent()`` will throw libtorrent_exception which derives from
// ``add_torrent()`` will throw system_error which derives from
// ``std::exception`` unless duplicate_is_error is set to false. In that
// case, add_torrent() will return the handle to the existing torrent.
//
@ -767,7 +767,7 @@ namespace libtorrent
// files downloaded by this torrent. To do so, pass in the value
// ``session::delete_files``. The removal of the torrent is asynchronous,
// there is no guarantee that adding the same torrent immediately after
// it was removed will not throw a libtorrent_exception exception. Once
// it was removed will not throw a system_error exception. Once
// the torrent is deleted, a torrent_deleted_alert is posted.
void remove_torrent(const torrent_handle& h, int options = 0);

View File

@ -226,7 +226,7 @@ namespace libtorrent
// uninitialized handle, it will throw ``invalid_handle``.
//
// .. warning::
// All operations on a torrent_handle may throw libtorrent_exception
// All operations on a torrent_handle may throw system_error
// exception, in case the handle is no longer referring to a torrent.
// There is one exception is_valid() will never throw. Since the torrents
// are processed by a background thread, there is no guarantee that a
@ -302,7 +302,7 @@ namespace libtorrent
// takes a reference to a vector that will be cleared and filled with one
// entry for each peer connected to this torrent, given the handle is
// valid. If the torrent_handle is invalid, it will throw
// libtorrent_exception exception. Each entry in the vector contains
// system_error exception. Each entry in the vector contains
// information about that particular peer. See peer_info.
void get_peer_info(std::vector<peer_info>& v) const;
@ -338,7 +338,7 @@ namespace libtorrent
// ``status()`` will return a structure with information about the status
// of this torrent. If the torrent_handle is invalid, it will throw
// libtorrent_exception exception. See torrent_status. The ``flags``
// system_error exception. See torrent_status. The ``flags``
// argument filters what information is returned in the torrent_status.
// Some information in there is relatively expensive to calculate, and if
// you're not interested in it (and see performance issues), you can
@ -1129,7 +1129,7 @@ namespace libtorrent
// not a member of this torrent, it will simply be disconnected. No harm
// can be done by using this other than an unnecessary connection attempt
// is made. If the torrent is uninitialized or in queued or checking
// mode, this will throw libtorrent_exception. The second (optional)
// mode, this will throw system_error. The second (optional)
// argument will be bitwised ORed into the source mask of this peer.
// Typically this is one of the source flags in peer_info. i.e.
// ``tracker``, ``pex``, ``dht`` etc.

View File

@ -113,11 +113,6 @@ namespace libtorrent
boost::uint8_t type;
};
#ifndef BOOST_NO_EXCEPTIONS
// for backwards compatibility with 0.14
typedef libtorrent_exception invalid_torrent_file;
#endif
// TODO: there may be some opportunities to optimize the size if torrent_info.
// specifically to turn some std::string and std::vector into pointers
class TORRENT_EXPORT torrent_info

View File

@ -85,6 +85,18 @@ namespace libtorrent
}
}
namespace
{
#ifndef BOOST_NO_EXCEPTIONS
TORRENT_NO_RETURN inline void throw_error()
{
throw system_error(error_code(errors::invalid_entry_type
, get_libtorrent_category()));
}
#endif
}
entry& entry::operator[](char const* key)
{
dictionary_type::iterator i = dict().find(key);
@ -140,8 +152,7 @@ namespace libtorrent
const entry& entry::operator[](std::string const& key) const
{
dictionary_type::const_iterator i = dict().find(key);
if (i == dict().end()) throw type_error(
(std::string("key not found: ") + key).c_str());
if (i == dict().end()) throw_error();
return i->second;
}
#endif
@ -174,7 +185,7 @@ namespace libtorrent
{
if (m_type == undefined_t) construct(int_t);
#ifndef BOOST_NO_EXCEPTIONS
if (m_type != int_t) throw_type_error();
if (m_type != int_t) throw_error();
#elif defined TORRENT_DEBUG
TORRENT_ASSERT(m_type_queried);
#endif
@ -185,7 +196,7 @@ namespace libtorrent
entry::integer_type const& entry::integer() const
{
#ifndef BOOST_NO_EXCEPTIONS
if (m_type != int_t) throw_type_error();
if (m_type != int_t) throw_error();
#elif defined TORRENT_DEBUG
TORRENT_ASSERT(m_type_queried);
#endif
@ -197,7 +208,7 @@ namespace libtorrent
{
if (m_type == undefined_t) construct(string_t);
#ifndef BOOST_NO_EXCEPTIONS
if (m_type != string_t) throw_type_error();
if (m_type != string_t) throw_error();
#elif defined TORRENT_DEBUG
TORRENT_ASSERT(m_type_queried);
#endif
@ -208,7 +219,7 @@ namespace libtorrent
entry::string_type const& entry::string() const
{
#ifndef BOOST_NO_EXCEPTIONS
if (m_type != string_t) throw_type_error();
if (m_type != string_t) throw_error();
#elif defined TORRENT_DEBUG
TORRENT_ASSERT(m_type_queried);
#endif
@ -220,7 +231,7 @@ namespace libtorrent
{
if (m_type == undefined_t) construct(list_t);
#ifndef BOOST_NO_EXCEPTIONS
if (m_type != list_t) throw_type_error();
if (m_type != list_t) throw_error();
#elif defined TORRENT_DEBUG
TORRENT_ASSERT(m_type_queried);
#endif
@ -231,7 +242,7 @@ namespace libtorrent
entry::list_type const& entry::list() const
{
#ifndef BOOST_NO_EXCEPTIONS
if (m_type != list_t) throw_type_error();
if (m_type != list_t) throw_error();
#elif defined TORRENT_DEBUG
TORRENT_ASSERT(m_type_queried);
#endif
@ -243,7 +254,7 @@ namespace libtorrent
{
if (m_type == undefined_t) construct(dictionary_t);
#ifndef BOOST_NO_EXCEPTIONS
if (m_type != dictionary_t) throw_type_error();
if (m_type != dictionary_t) throw_error();
#elif defined TORRENT_DEBUG
TORRENT_ASSERT(m_type_queried);
#endif
@ -254,7 +265,7 @@ namespace libtorrent
entry::dictionary_type const& entry::dict() const
{
#ifndef BOOST_NO_EXCEPTIONS
if (m_type != dictionary_t) throw_type_error();
if (m_type != dictionary_t) throw_error();
#elif defined TORRENT_DEBUG
TORRENT_ASSERT(m_type_queried);
#endif
@ -266,7 +277,7 @@ namespace libtorrent
{
if (m_type == undefined_t) construct(preformatted_t);
#ifndef BOOST_NO_EXCEPTIONS
if (m_type != preformatted_t) throw_type_error();
if (m_type != preformatted_t) throw_error();
#elif defined TORRENT_DEBUG
TORRENT_ASSERT(m_type_queried);
#endif
@ -277,7 +288,7 @@ namespace libtorrent
entry::preformatted_type const& entry::preformatted() const
{
#ifndef BOOST_NO_EXCEPTIONS
if (m_type != preformatted_t) throw_type_error();
if (m_type != preformatted_t) throw_error();
#elif defined TORRENT_DEBUG
TORRENT_ASSERT(m_type_queried);
#endif

View File

@ -322,24 +322,6 @@ namespace libtorrent
return http_category;
}
#ifndef BOOST_NO_EXCEPTIONS
const char* libtorrent_exception::what() const TORRENT_EXCEPTION_THROW_SPECIFIER
{
if (!m_msg)
{
std::string msg = convert_from_native(m_error.message());
m_msg = allocate_string_copy(msg.c_str());
}
return m_msg;
}
libtorrent_exception::~libtorrent_exception() TORRENT_EXCEPTION_THROW_SPECIFIER
{
free(m_msg);
}
#endif
namespace errors
{
// hidden

View File

@ -169,7 +169,7 @@ namespace libtorrent
{
error_code ec;
torrent_handle ret = add_magnet_uri_deprecated(ses, uri, p, ec);
if (ec) throw libtorrent_exception(ec);
if (ec) throw system_error(ec);
return ret;
}
#endif // BOOST_NO_EXCEPTIONS

View File

@ -290,7 +290,7 @@ namespace libtorrent
#endif
error_code ec;
torrent_handle r = TORRENT_SYNC_CALL_RET2(torrent_handle, add_torrent, p, boost::ref(ec));
if (ec) throw libtorrent_exception(ec);
if (ec) throw system_error(ec);
return r;
}
#endif
@ -649,7 +649,7 @@ namespace libtorrent
TORRENT_ASSERT(ret == 0);
#ifndef BOOST_NO_EXCEPTIONS
if (ret != 0) throw libtorrent_exception(ec);
if (ret != 0) throw system_error(ec);
#endif
TORRENT_SYNC_CALL2(load_state, &e, flags);
}
@ -675,7 +675,7 @@ namespace libtorrent
TORRENT_ASSERT(ret == 0);
#ifndef BOOST_NO_EXCEPTIONS
if (ret != 0) throw libtorrent_exception(ec);
if (ret != 0) throw system_error(ec);
#endif
TORRENT_SYNC_CALL2(load_state, &e, flags);
}

View File

@ -149,7 +149,7 @@ namespace libtorrent
#ifndef BOOST_NO_EXCEPTIONS
void throw_invalid_handle()
{
throw libtorrent_exception(errors::invalid_torrent_handle);
throw system_error(errors::invalid_torrent_handle);
}
#endif

View File

@ -799,14 +799,14 @@ namespace libtorrent
if (bdecode(buf.first, buf.first + buf.second, e, ec) != 0)
{
#ifndef BOOST_NO_EXCEPTIONS
throw invalid_torrent_file(ec);
throw system_error(ec);
#else
return;
#endif
}
#ifndef BOOST_NO_EXCEPTIONS
if (!parse_torrent_file(e, ec, 0))
throw invalid_torrent_file(ec);
throw system_error(ec);
#else
parse_torrent_file(e, ec, 0);
#endif
@ -831,14 +831,14 @@ namespace libtorrent
if (tmp.empty() || bdecode(&tmp[0], &tmp[0] + tmp.size(), e, ec) != 0)
{
#ifndef BOOST_NO_EXCEPTIONS
throw invalid_torrent_file(ec);
throw system_error(ec);
#else
return;
#endif
}
#ifndef BOOST_NO_EXCEPTIONS
if (!parse_torrent_file(e, ec, 0))
throw invalid_torrent_file(ec);
throw system_error(ec);
#else
parse_torrent_file(e, ec, 0);
#endif
@ -858,7 +858,7 @@ namespace libtorrent
{
error_code ec;
if (!parse_torrent_file(torrent_file, ec, flags))
throw invalid_torrent_file(ec);
throw system_error(ec);
INVARIANT_CHECK;
}
@ -875,10 +875,10 @@ namespace libtorrent
error_code ec;
bdecode_node e;
if (bdecode(buffer, buffer + size, e, ec) != 0)
throw invalid_torrent_file(ec);
throw system_error(ec);
if (!parse_torrent_file(e, ec, flags))
throw invalid_torrent_file(ec);
throw system_error(ec);
INVARIANT_CHECK;
}
@ -895,14 +895,14 @@ namespace libtorrent
std::vector<char> buf;
error_code ec;
int ret = load_file(filename, buf, ec);
if (ret < 0) throw invalid_torrent_file(ec);
if (ret < 0) throw system_error(ec);
bdecode_node e;
if (buf.empty() || bdecode(&buf[0], &buf[0] + buf.size(), e, ec) != 0)
throw invalid_torrent_file(ec);
throw system_error(ec);
if (!parse_torrent_file(e, ec, flags))
throw invalid_torrent_file(ec);
throw system_error(ec);
INVARIANT_CHECK;
}
@ -923,14 +923,14 @@ namespace libtorrent
wchar_utf8(filename, utf8);
error_code ec;
int ret = load_file(utf8, buf, ec);
if (ret < 0) throw invalid_torrent_file(ec);
if (ret < 0) throw system_error(ec);
bdecode_node e;
if (buf.empty() || bdecode(&buf[0], &buf[0] + buf.size(), e, ec) != 0)
throw invalid_torrent_file(ec);
throw system_error(ec);
if (!parse_torrent_file(e, ec, flags))
throw invalid_torrent_file(ec);
throw system_error(ec);
INVARIANT_CHECK;
}

View File

@ -868,9 +868,9 @@ TORRENT_TEST(empty_file2)
auto ti = boost::make_shared<torrent_info>("", 0);
TEST_ERROR("expected exception thrown");
}
catch (libtorrent_exception& e)
catch (system_error& e)
{
printf("Expected error: %s\n", e.error().message().c_str());
printf("Expected error: %s\n", e.code().message().c_str());
}
}