Added more error code values.

I have not set error code for all exception invocation.
In this change, I set error code where error likely occurs.
pull/1/head
Tatsuhiro Tsujikawa 2010-12-01 21:26:58 +09:00
parent 6bc215fcec
commit f0f4f8f703
24 changed files with 275 additions and 123 deletions

View File

@ -65,6 +65,7 @@
#include "NameResolver.h" #include "NameResolver.h"
#include "uri.h" #include "uri.h"
#include "FileEntry.h" #include "FileEntry.h"
#include "error_code.h"
#ifdef ENABLE_ASYNC_DNS #ifdef ENABLE_ASYNC_DNS
#include "AsyncNameResolver.h" #include "AsyncNameResolver.h"
#endif // ENABLE_ASYNC_DNS #endif // ENABLE_ASYNC_DNS
@ -650,11 +651,12 @@ bool AbstractCommand::asyncResolveHostname()
e_->getRequestGroupMan()->getOrCreateServerStat e_->getRequestGroupMan()->getOrCreateServerStat
(req_->getHost(), req_->getProtocol())->setError(); (req_->getHost(), req_->getProtocol())->setError();
} }
throw DL_ABORT_EX throw DL_ABORT_EX2
(fmt(MSG_NAME_RESOLUTION_FAILED, (fmt(MSG_NAME_RESOLUTION_FAILED,
getCuid(), getCuid(),
asyncNameResolver_->getHostname().c_str(), asyncNameResolver_->getHostname().c_str(),
asyncNameResolver_->getError().c_str())); asyncNameResolver_->getError().c_str()),
error_code::NAME_RESOLVE_ERROR);
default: default:
return false; return false;
} }

View File

@ -51,6 +51,7 @@
#include "a2io.h" #include "a2io.h"
#include "fmt.h" #include "fmt.h"
#include "DownloadFailureException.h" #include "DownloadFailureException.h"
#include "error_code.h"
namespace aria2 { namespace aria2 {
@ -100,10 +101,12 @@ void AbstractDiskWriter::openExistingFile(uint64_t totalLength)
errno == EINTR); errno == EINTR);
if(fd_ < 0) { if(fd_ < 0) {
int errNum = errno; int errNum = errno;
throw DL_ABORT_EX2 throw DL_ABORT_EX3
(errNum, fmt(EX_FILE_OPEN, (errNum,
fmt(EX_FILE_OPEN,
filename_.c_str(), filename_.c_str(),
util::safeStrerror(errNum).c_str())); util::safeStrerror(errNum).c_str()),
error_code::FILE_OPEN_ERROR);
} }
} }
@ -116,10 +119,12 @@ void AbstractDiskWriter::createFile(int addFlags)
OPEN_MODE)) == -1 && errno == EINTR); OPEN_MODE)) == -1 && errno == EINTR);
if(fd_ < 0) { if(fd_ < 0) {
int errNum = errno; int errNum = errno;
throw DL_ABORT_EX2 throw DL_ABORT_EX3
(errNum, fmt(EX_FILE_OPEN, (errNum,
fmt(EX_FILE_OPEN,
filename_.c_str(), filename_.c_str(),
util::safeStrerror(errNum).c_str())); util::safeStrerror(errNum).c_str()),
error_code::FILE_CREATE_ERROR);
} }
} }
@ -148,9 +153,10 @@ void AbstractDiskWriter::seek(off_t offset)
{ {
if(a2lseek(fd_, offset, SEEK_SET) == (off_t)-1) { if(a2lseek(fd_, offset, SEEK_SET) == (off_t)-1) {
int errNum = errno; int errNum = errno;
throw DL_ABORT_EX(fmt(EX_FILE_SEEK, throw DL_ABORT_EX2(fmt(EX_FILE_SEEK,
filename_.c_str(), filename_.c_str(),
util::safeStrerror(errNum).c_str())); util::safeStrerror(errNum).c_str()),
error_code::FILE_IO_ERROR);
} }
} }
@ -162,16 +168,19 @@ void AbstractDiskWriter::writeData(const unsigned char* data, size_t len, off_t
// If errno is ENOSPC(not enough space in device), throw // If errno is ENOSPC(not enough space in device), throw
// DownloadFailureException and abort download instantly. // DownloadFailureException and abort download instantly.
if(errNum == ENOSPC) { if(errNum == ENOSPC) {
throw DOWNLOAD_FAILURE_EXCEPTION2 throw DOWNLOAD_FAILURE_EXCEPTION3
(fmt(EX_FILE_WRITE, (errNum,
fmt(EX_FILE_WRITE,
filename_.c_str(), filename_.c_str(),
util::safeStrerror(errNum).c_str()), util::safeStrerror(errNum).c_str()),
error_code::NOT_ENOUGH_DISK_SPACE); error_code::NOT_ENOUGH_DISK_SPACE);
} else { } else {
throw DL_ABORT_EX throw DL_ABORT_EX3
(fmt(EX_FILE_WRITE, (errNum,
fmt(EX_FILE_WRITE,
filename_.c_str(), filename_.c_str(),
util::safeStrerror(errNum).c_str())); util::safeStrerror(errNum).c_str()),
error_code::FILE_IO_ERROR);
} }
} }
} }
@ -182,10 +191,12 @@ ssize_t AbstractDiskWriter::readData(unsigned char* data, size_t len, off_t offs
seek(offset); seek(offset);
if((ret = readDataInternal(data, len)) < 0) { if((ret = readDataInternal(data, len)) < 0) {
int errNum = errno; int errNum = errno;
throw DL_ABORT_EX throw DL_ABORT_EX3
(fmt(EX_FILE_READ, (errNum,
fmt(EX_FILE_READ,
filename_.c_str(), filename_.c_str(),
util::safeStrerror(errNum).c_str())); util::safeStrerror(errNum).c_str()),
error_code::FILE_IO_ERROR);
} }
return ret; return ret;
} }
@ -201,14 +212,17 @@ void AbstractDiskWriter::truncate(uint64_t length)
HANDLE handle = LongToHandle(_get_osfhandle(fd_)); HANDLE handle = LongToHandle(_get_osfhandle(fd_));
seek(length); seek(length);
if(SetEndOfFile(handle) == 0) { if(SetEndOfFile(handle) == 0) {
throw DL_ABORT_EX(fmt("SetEndOfFile failed. cause: %s", throw DL_ABORT_EX2(fmt("SetEndOfFile failed. cause: %s",
GetLastError())); GetLastError()),
error_code::FILE_IO_ERROR);
} }
#else #else
if(ftruncate(fd_, length) == -1) { if(ftruncate(fd_, length) == -1) {
int errNum = errno; int errNum = errno;
throw DL_ABORT_EX(fmt("ftruncate failed. cause: %s", throw DL_ABORT_EX3(errNum,
util::safeStrerror(errNum).c_str())); fmt("ftruncate failed. cause: %s",
util::safeStrerror(errNum).c_str()),
error_code::FILE_IO_ERROR);
} }
#endif #endif
} }
@ -226,14 +240,18 @@ void AbstractDiskWriter::allocate(off_t offset, uint64_t length)
while((r = fallocate(fd_, 0, offset, length)) == -1 && errno == EINTR); while((r = fallocate(fd_, 0, offset, length)) == -1 && errno == EINTR);
int errNum = errno; int errNum = errno;
if(r == -1) { if(r == -1) {
throw DL_ABORT_EX(fmt("fallocate failed. cause: %s", throw DL_ABORT_EX3(errNum,
util::safeStrerror(errNum).c_str())); fmt("fallocate failed. cause: %s",
util::safeStrerror(errNum).c_str()),
error_code::FILE_IO_ERROR);
} }
# elif HAVE_POSIX_FALLOCATE # elif HAVE_POSIX_FALLOCATE
int r = posix_fallocate(fd_, offset, length); int r = posix_fallocate(fd_, offset, length);
if(r != 0) { if(r != 0) {
throw DL_ABORT_EX(fmt("posix_fallocate failed. cause: %s", throw DL_ABORT_EX3(errNum,
util::safeStrerror(r).c_str())); fmt("posix_fallocate failed. cause: %s",
util::safeStrerror(r).c_str()),
error_code::FILE_IO_ERROR);
} }
# else # else
# error "no *_fallocate function available." # error "no *_fallocate function available."

View File

@ -58,7 +58,7 @@ public:
#define DL_ABORT_EX(arg) DlAbortEx(__FILE__, __LINE__, arg) #define DL_ABORT_EX(arg) DlAbortEx(__FILE__, __LINE__, arg)
#define DL_ABORT_EX2(arg1, arg2) DlAbortEx(__FILE__, __LINE__, arg1, arg2) #define DL_ABORT_EX2(arg1, arg2) DlAbortEx(__FILE__, __LINE__, arg1, arg2)
#define DL_ABORT_EX3(arg1, arg2, arg3)\ #define DL_ABORT_EX3(arg1, arg2, arg3) \
DlAbortEx(__FILE__, __LINE__, arg1, arg2, arg3) DlAbortEx(__FILE__, __LINE__, arg1, arg2, arg3)
} // namespace aria2 } // namespace aria2

View File

@ -57,4 +57,11 @@ DownloadFailureException::DownloadFailureException
error_code::Value code): error_code::Value code):
RecoverableException(file, line, msg, code) {} RecoverableException(file, line, msg, code) {}
DownloadFailureException::DownloadFailureException
(const char* file, int line,
int errNum,
const std::string& msg,
error_code::Value code):
RecoverableException(file, line, errNum, msg, code) {}
} // namespace aria2 } // namespace aria2

View File

@ -54,12 +54,19 @@ public:
DownloadFailureException(const char* file, int line, DownloadFailureException(const char* file, int line,
const std::string& msg, const std::string& msg,
error_code::Value code); error_code::Value code);
DownloadFailureException(const char* file, int line,
int errNum,
const std::string& msg,
error_code::Value code);
}; };
#define DOWNLOAD_FAILURE_EXCEPTION(arg) \ #define DOWNLOAD_FAILURE_EXCEPTION(arg) \
DownloadFailureException(__FILE__, __LINE__, arg) DownloadFailureException(__FILE__, __LINE__, arg)
#define DOWNLOAD_FAILURE_EXCEPTION2(arg1, arg2) \ #define DOWNLOAD_FAILURE_EXCEPTION2(arg1, arg2) \
DownloadFailureException(__FILE__, __LINE__, arg1, arg2) DownloadFailureException(__FILE__, __LINE__, arg1, arg2)
#define DOWNLOAD_FAILURE_EXCEPTION3(arg1, arg2, arg3) \
DownloadFailureException(__FILE__, __LINE__, arg1, arg2, arg3)
} // namespace aria2 } // namespace aria2

View File

@ -53,13 +53,27 @@ Exception::Exception
(const char* file, (const char* file,
int line, int line,
const std::string& msg, const std::string& msg,
error_code::Value errorCode,
const Exception& cause) const Exception& cause)
: file_(file), : file_(file),
line_(line), line_(line),
errNum_(0), errNum_(0),
msg_(msg), msg_(msg),
cause_(cause.copy()), errorCode_(errorCode),
errorCode_(cause.errorCode_) cause_(cause.copy())
{}
Exception::Exception
(const char* file,
int line,
const std::string& msg,
const Exception& cause)
: file_(file),
line_(line),
errNum_(0),
msg_(msg),
errorCode_(cause.errorCode_),
cause_(cause.copy())
{} {}
Exception::Exception Exception::Exception

View File

@ -53,16 +53,20 @@ private:
int errNum_; int errNum_;
std::string msg_; std::string msg_;
// This is application-level error code.
error_code::Value errorCode_;
// Exception that this object wraps. Normally this cause_ is the // Exception that this object wraps. Normally this cause_ is the
// root cause of this exception. // root cause of this exception.
SharedHandle<Exception> cause_; SharedHandle<Exception> cause_;
// This is application-level error code.
error_code::Value errorCode_;
protected: protected:
virtual SharedHandle<Exception> copy() const = 0; virtual SharedHandle<Exception> copy() const = 0;
public: public:
Exception(const char* file, int line, const std::string& msg); Exception(const char* file, int line, const std::string& msg);
Exception(const char* file, int line, const std::string& msg,
error_code::Value errorCode,
const Exception& cause);
// errorCode_ is initializedwith cause.errorCode_. // errorCode_ is initializedwith cause.errorCode_.
Exception(const char* file, int line, const std::string& msg, Exception(const char* file, int line, const std::string& msg,
const Exception& cause); const Exception& cause);

View File

@ -46,6 +46,7 @@
#include "DlAbortEx.h" #include "DlAbortEx.h"
#include "MetalinkParserState.h" #include "MetalinkParserState.h"
#include "A2STR.h" #include "A2STR.h"
#include "error_code.h"
namespace aria2 { namespace aria2 {
@ -158,16 +159,19 @@ namespace {
void checkError(XML_Parser parser) void checkError(XML_Parser parser)
{ {
if(XML_Parse(parser, 0, 0, 1) == XML_STATUS_ERROR) { if(XML_Parse(parser, 0, 0, 1) == XML_STATUS_ERROR) {
throw DL_ABORT_EX(MSG_CANNOT_PARSE_METALINK); throw DL_ABORT_EX2(MSG_CANNOT_PARSE_METALINK,
error_code::METALINK_PARSE_ERROR);
} }
SessionData* sessionData = SessionData* sessionData =
reinterpret_cast<SessionData*>(XML_GetUserData(parser)); reinterpret_cast<SessionData*>(XML_GetUserData(parser));
const SharedHandle<MetalinkParserStateMachine>& stm = sessionData->stm_; const SharedHandle<MetalinkParserStateMachine>& stm = sessionData->stm_;
if(!stm->finished()) { if(!stm->finished()) {
throw DL_ABORT_EX(MSG_CANNOT_PARSE_METALINK); throw DL_ABORT_EX2(MSG_CANNOT_PARSE_METALINK,
error_code::METALINK_PARSE_ERROR);
} }
if(!stm->getErrors().empty()) { if(!stm->getErrors().empty()) {
throw DL_ABORT_EX(stm->getErrorString()); throw DL_ABORT_EX2(stm->getErrorString(),
error_code::METALINK_PARSE_ERROR);
} }
} }
} // namespace } // namespace
@ -195,11 +199,13 @@ MetalinkProcessor::parseFile(std::istream& stream)
while(stream) { while(stream) {
stream.read(buf, sizeof(buf)); stream.read(buf, sizeof(buf));
if(XML_Parse(parser, buf, stream.gcount(), 0) == XML_STATUS_ERROR) { if(XML_Parse(parser, buf, stream.gcount(), 0) == XML_STATUS_ERROR) {
throw DL_ABORT_EX(MSG_CANNOT_PARSE_METALINK); throw DL_ABORT_EX2(MSG_CANNOT_PARSE_METALINK,
error_code::METALINK_PARSE_ERROR);
} }
} }
if(stream.bad()) { if(stream.bad()) {
throw DL_ABORT_EX(MSG_CANNOT_PARSE_METALINK); throw DL_ABORT_EX2(MSG_CANNOT_PARSE_METALINK,
error_code::METALINK_PARSE_ERROR);
} }
checkError(parser); checkError(parser);
return stm_->getResult(); return stm_->getResult();
@ -223,7 +229,8 @@ MetalinkProcessor::parseFromBinaryStream(const SharedHandle<BinaryStream>& binar
} }
if(XML_Parse(parser, reinterpret_cast<const char*>(buf), res, 0) == if(XML_Parse(parser, reinterpret_cast<const char*>(buf), res, 0) ==
XML_STATUS_ERROR) { XML_STATUS_ERROR) {
throw DL_ABORT_EX(MSG_CANNOT_PARSE_METALINK); throw DL_ABORT_EX2(MSG_CANNOT_PARSE_METALINK,
error_code::METALINK_PARSE_ERROR);
} }
readOffset += res; readOffset += res;
} }

View File

@ -56,6 +56,7 @@
#include "AuthConfig.h" #include "AuthConfig.h"
#include "a2functional.h" #include "a2functional.h"
#include "util.h" #include "util.h"
#include "error_code.h"
namespace aria2 { namespace aria2 {
@ -382,7 +383,8 @@ bool FtpConnection::bulkReceiveResponse
if(strbuf_.size() >= 4) { if(strbuf_.size() >= 4) {
status = getStatus(strbuf_); status = getStatus(strbuf_);
if(status == 0) { if(status == 0) {
throw DL_ABORT_EX(EX_INVALID_RESPONSE); throw DL_ABORT_EX2(EX_INVALID_RESPONSE,
error_code::FTP_PROTOCOL_ERROR);
} }
} else { } else {
return false; return false;
@ -549,7 +551,8 @@ unsigned int FtpConnection::receivePwdResponse(std::string& pwd)
(last = response.second.find("\"", ++first)) != std::string::npos) { (last = response.second.find("\"", ++first)) != std::string::npos) {
pwd = response.second.substr(first, last-first); pwd = response.second.substr(first, last-first);
} else { } else {
throw DL_ABORT_EX(EX_INVALID_RESPONSE); throw DL_ABORT_EX2(EX_INVALID_RESPONSE,
error_code::FTP_PROTOCOL_ERROR);
} }
} }
return response.first; return response.first;

View File

@ -72,6 +72,7 @@
#include "HttpResponse.h" #include "HttpResponse.h"
#include "DlRetryEx.h" #include "DlRetryEx.h"
#include "CheckIntegrityEntry.h" #include "CheckIntegrityEntry.h"
#include "error_code.h"
namespace aria2 { namespace aria2 {
@ -154,7 +155,7 @@ bool FtpNegotiationCommand::recvGreeting() {
return false; return false;
} }
if(status != 220) { if(status != 220) {
throw DL_ABORT_EX(EX_CONNECTION_FAILED); throw DL_ABORT_EX2(EX_CONNECTION_FAILED, error_code::FTP_PROTOCOL_ERROR);
} }
sequence_ = SEQ_SEND_USER; sequence_ = SEQ_SEND_USER;
@ -183,7 +184,8 @@ bool FtpNegotiationCommand::recvUser() {
sequence_ = SEQ_SEND_PASS; sequence_ = SEQ_SEND_PASS;
break; break;
default: default:
throw DL_ABORT_EX(fmt(EX_BAD_STATUS, status)); throw DL_ABORT_EX2(fmt(EX_BAD_STATUS, status),
error_code::FTP_PROTOCOL_ERROR);
} }
return true; return true;
} }
@ -204,7 +206,8 @@ bool FtpNegotiationCommand::recvPass() {
return false; return false;
} }
if(status != 230) { if(status != 230) {
throw DL_ABORT_EX(fmt(EX_BAD_STATUS, status)); throw DL_ABORT_EX2(fmt(EX_BAD_STATUS, status),
error_code::FTP_PROTOCOL_ERROR);
} }
sequence_ = SEQ_SEND_TYPE; sequence_ = SEQ_SEND_TYPE;
return true; return true;
@ -226,7 +229,8 @@ bool FtpNegotiationCommand::recvType() {
return false; return false;
} }
if(status != 200) { if(status != 200) {
throw DL_ABORT_EX(fmt(EX_BAD_STATUS, status)); throw DL_ABORT_EX2(fmt(EX_BAD_STATUS, status),
error_code::FTP_PROTOCOL_ERROR);
} }
sequence_ = SEQ_SEND_PWD; sequence_ = SEQ_SEND_PWD;
return true; return true;
@ -251,7 +255,8 @@ bool FtpNegotiationCommand::recvPwd()
return false; return false;
} }
if(status != 257) { if(status != 257) {
throw DL_ABORT_EX(fmt(EX_BAD_STATUS, status)); throw DL_ABORT_EX2(fmt(EX_BAD_STATUS, status),
error_code::FTP_PROTOCOL_ERROR);
} }
ftp_->setBaseWorkingDir(pwd); ftp_->setBaseWorkingDir(pwd);
A2_LOG_INFO(fmt("CUID#%lld - base working directory is '%s'", A2_LOG_INFO(fmt("CUID#%lld - base working directory is '%s'",
@ -295,7 +300,8 @@ bool FtpNegotiationCommand::recvCwd()
throw DL_ABORT_EX2(MSG_RESOURCE_NOT_FOUND, throw DL_ABORT_EX2(MSG_RESOURCE_NOT_FOUND,
error_code::RESOURCE_NOT_FOUND); error_code::RESOURCE_NOT_FOUND);
else else
throw DL_ABORT_EX(fmt(EX_BAD_STATUS, status)); throw DL_ABORT_EX2(fmt(EX_BAD_STATUS, status),
error_code::FTP_PROTOCOL_ERROR);
} }
cwdDirs_.pop_front(); cwdDirs_.pop_front();
if(cwdDirs_.empty()) { if(cwdDirs_.empty()) {
@ -461,9 +467,10 @@ bool FtpNegotiationCommand::recvSize() {
if(status == 213) { if(status == 213) {
if(size > INT64_MAX) { if(size > INT64_MAX) {
throw DL_ABORT_EX throw DL_ABORT_EX2
(fmt(EX_TOO_LARGE_FILE, (fmt(EX_TOO_LARGE_FILE,
util::uitos(size, true).c_str())); util::uitos(size, true).c_str()),
error_code::FTP_PROTOCOL_ERROR);
} }
if(!getPieceStorage()) { if(!getPieceStorage()) {
@ -563,7 +570,8 @@ bool FtpNegotiationCommand::recvPort() {
return false; return false;
} }
if(status != 200) { if(status != 200) {
throw DL_ABORT_EX(fmt(EX_BAD_STATUS, status)); throw DL_ABORT_EX2(fmt(EX_BAD_STATUS, status),
error_code::FTP_PROTOCOL_ERROR);
} }
sequence_ = SEQ_SEND_REST; sequence_ = SEQ_SEND_REST;
return true; return true;
@ -624,7 +632,8 @@ bool FtpNegotiationCommand::recvPasv() {
return false; return false;
} }
if(status != 227) { if(status != 227) {
throw DL_ABORT_EX(fmt(EX_BAD_STATUS, status)); throw DL_ABORT_EX2(fmt(EX_BAD_STATUS, status),
error_code::FTP_PROTOCOL_ERROR);
} }
dataConnAddr_ = dest; dataConnAddr_ = dest;
@ -744,8 +753,9 @@ bool FtpNegotiationCommand::sendRestPasv(const SharedHandle<Segment>& segment) {
// Check connection is made properly // Check connection is made properly
if(dataSocket_->isReadable(0)) { if(dataSocket_->isReadable(0)) {
std::string error = dataSocket_->getSocketError(); std::string error = dataSocket_->getSocketError();
throw DL_ABORT_EX throw DL_ABORT_EX2
(fmt(MSG_ESTABLISHING_CONNECTION_FAILED, error.c_str())); (fmt(MSG_ESTABLISHING_CONNECTION_FAILED, error.c_str()),
error_code::FTP_PROTOCOL_ERROR);
} }
setReadCheckSocket(getSocket()); setReadCheckSocket(getSocket());
disableWriteCheckSocket(); disableWriteCheckSocket();
@ -800,7 +810,8 @@ bool FtpNegotiationCommand::recvRetr() {
throw DL_ABORT_EX2(MSG_RESOURCE_NOT_FOUND, throw DL_ABORT_EX2(MSG_RESOURCE_NOT_FOUND,
error_code::RESOURCE_NOT_FOUND); error_code::RESOURCE_NOT_FOUND);
else else
throw DL_ABORT_EX(fmt(EX_BAD_STATUS, status)); throw DL_ABORT_EX2(fmt(EX_BAD_STATUS, status),
error_code::FTP_PROTOCOL_ERROR);
} }
if(getOption()->getAsBool(PREF_FTP_PASV)) { if(getOption()->getAsBool(PREF_FTP_PASV)) {
sequence_ = SEQ_NEGOTIATION_COMPLETED; sequence_ = SEQ_NEGOTIATION_COMPLETED;

View File

@ -43,6 +43,7 @@
#include "DlRetryEx.h" #include "DlRetryEx.h"
#include "DlAbortEx.h" #include "DlAbortEx.h"
#include "A2STR.h" #include "A2STR.h"
#include "error_code.h"
namespace aria2 { namespace aria2 {
@ -71,7 +72,8 @@ void HttpHeaderProcessor::update(const std::string& data)
void HttpHeaderProcessor::checkHeaderLimit(size_t incomingLength) void HttpHeaderProcessor::checkHeaderLimit(size_t incomingLength)
{ {
if(buf_.size()+incomingLength > limit_) { if(buf_.size()+incomingLength > limit_) {
throw DL_ABORT_EX("Too large http header"); throw DL_ABORT_EX2("Too large http header",
error_code::HTTP_PROTOCOL_ERROR);
} }
} }
@ -138,7 +140,8 @@ SharedHandle<HttpHeader> HttpHeaderProcessor::getHttpRequestHeader()
std::vector<std::string> firstLine; std::vector<std::string> firstLine;
util::split(buf_.substr(0, delimpos), std::back_inserter(firstLine)," ",true); util::split(buf_.substr(0, delimpos), std::back_inserter(firstLine)," ",true);
if(firstLine.size() != 3) { if(firstLine.size() != 3) {
throw DL_ABORT_EX("Malformed HTTP request header."); throw DL_ABORT_EX2("Malformed HTTP request header.",
error_code::HTTP_PROTOCOL_ERROR);
} }
SharedHandle<HttpHeader> httpHeader(new HttpHeader()); SharedHandle<HttpHeader> httpHeader(new HttpHeader());
httpHeader->setMethod(firstLine[0]); httpHeader->setMethod(firstLine[0]);

View File

@ -50,6 +50,7 @@
#include "AuthConfigFactory.h" #include "AuthConfigFactory.h"
#include "AuthConfig.h" #include "AuthConfig.h"
#include "ChunkedDecodingStreamFilter.h" #include "ChunkedDecodingStreamFilter.h"
#include "error_code.h"
#ifdef HAVE_LIBZ #ifdef HAVE_LIBZ
# include "GZipDecodingStreamFilter.h" # include "GZipDecodingStreamFilter.h"
#endif // HAVE_LIBZ #endif // HAVE_LIBZ
@ -70,14 +71,16 @@ void HttpResponse::validateResponse() const
} }
if(statusCode == 304) { if(statusCode == 304) {
if(httpRequest_->getIfModifiedSinceHeader().empty()) { if(httpRequest_->getIfModifiedSinceHeader().empty()) {
throw DL_ABORT_EX("Got 304 without If-Modified-Since"); throw DL_ABORT_EX2("Got 304 without If-Modified-Since",
error_code::HTTP_PROTOCOL_ERROR);
} }
} else if(statusCode == 301 || } else if(statusCode == 301 ||
statusCode == 302 || statusCode == 302 ||
statusCode == 303 || statusCode == 303 ||
statusCode == 307) { statusCode == 307) {
if(!httpHeader_->defined(HttpHeader::LOCATION)) { if(!httpHeader_->defined(HttpHeader::LOCATION)) {
throw DL_ABORT_EX(fmt(EX_LOCATION_HEADER_REQUIRED, statusCode)); throw DL_ABORT_EX2(fmt(EX_LOCATION_HEADER_REQUIRED, statusCode),
error_code::HTTP_PROTOCOL_ERROR);
} }
return; return;
} else if(statusCode == 200 || statusCode == 206) { } else if(statusCode == 200 || statusCode == 206) {
@ -97,7 +100,8 @@ void HttpResponse::validateResponse() const
} }
} }
} else { } else {
throw DL_ABORT_EX(fmt("Unexpected status %d", statusCode)); throw DL_ABORT_EX2(fmt("Unexpected status %d", statusCode),
error_code::HTTP_PROTOCOL_ERROR);
} }
} }

View File

@ -58,6 +58,7 @@
#include "BinaryStream.h" #include "BinaryStream.h"
#include "NullSinkStreamFilter.h" #include "NullSinkStreamFilter.h"
#include "SinkStreamFilter.h" #include "SinkStreamFilter.h"
#include "error_code.h"
namespace aria2 { namespace aria2 {
@ -175,7 +176,8 @@ bool HttpSkipResponseCommand::processResponse()
unsigned int rnum = unsigned int rnum =
httpResponse_->getHttpRequest()->getRequest()->getRedirectCount(); httpResponse_->getHttpRequest()->getRequest()->getRedirectCount();
if(rnum >= Request::MAX_REDIRECT) { if(rnum >= Request::MAX_REDIRECT) {
throw DL_ABORT_EX(fmt("Too many redirects: count=%u", rnum)); throw DL_ABORT_EX2(fmt("Too many redirects: count=%u", rnum),
error_code::HTTP_TOO_MANY_REDIRECTS);
} }
httpResponse_->processRedirect(); httpResponse_->processRedirect();
return prepareForRetry(0); return prepareForRetry(0);
@ -187,13 +189,15 @@ bool HttpSkipResponseCommand::processResponse()
(getRequest()->getHost(), getRequest()->getDir(), getOption().get())) { (getRequest()->getHost(), getRequest()->getDir(), getOption().get())) {
return prepareForRetry(0); return prepareForRetry(0);
} else { } else {
throw DL_ABORT_EX(EX_AUTH_FAILED); throw DL_ABORT_EX2(EX_AUTH_FAILED,
error_code::HTTP_AUTH_FAILED);
} }
} else if(statusCode == 404) { } else if(statusCode == 404) {
throw DL_ABORT_EX2(MSG_RESOURCE_NOT_FOUND, throw DL_ABORT_EX2(MSG_RESOURCE_NOT_FOUND,
error_code::RESOURCE_NOT_FOUND); error_code::RESOURCE_NOT_FOUND);
} else { } else {
throw DL_ABORT_EX(fmt(EX_BAD_STATUS, statusCode)); throw DL_ABORT_EX2(fmt(EX_BAD_STATUS, statusCode),
error_code::HTTP_PROTOCOL_ERROR);
} }
} else { } else {
return prepareForRetry(0); return prepareForRetry(0);

View File

@ -41,6 +41,7 @@
#include "fmt.h" #include "fmt.h"
#include "util.h" #include "util.h"
#include "SocketCore.h" #include "SocketCore.h"
#include "error_code.h"
namespace aria2 { namespace aria2 {
@ -53,8 +54,9 @@ void NameResolver::resolve(std::vector<std::string>& resolvedAddresses,
int s; int s;
s = callGetaddrinfo(&res, hostname.c_str(), 0, family_, socktype_, 0, 0); s = callGetaddrinfo(&res, hostname.c_str(), 0, family_, socktype_, 0, 0);
if(s) { if(s) {
throw DL_ABORT_EX(fmt(EX_RESOLVE_HOSTNAME, throw DL_ABORT_EX2(fmt(EX_RESOLVE_HOSTNAME,
hostname.c_str(), gai_strerror(s))); hostname.c_str(), gai_strerror(s)),
error_code::NAME_RESOLVE_ERROR);
} }
WSAAPI_AUTO_DELETE<struct addrinfo*> resDeleter(res, freeaddrinfo); WSAAPI_AUTO_DELETE<struct addrinfo*> resDeleter(res, freeaddrinfo);
struct addrinfo* rp; struct addrinfo* rp;

View File

@ -43,14 +43,15 @@ const std::string OptionHandlerException::MESSAGE
OptionHandlerException::OptionHandlerException(const char* file, int line, OptionHandlerException::OptionHandlerException(const char* file, int line,
const std::string& optName): const std::string& optName):
RecoverableException RecoverableException
(file, line, fmt(MESSAGE.c_str(), optName.c_str())), (file, line, fmt(MESSAGE.c_str(), optName.c_str()), error_code::OPTION_ERROR),
optName_(optName) {} optName_(optName) {}
OptionHandlerException::OptionHandlerException(const char* file, int line, OptionHandlerException::OptionHandlerException(const char* file, int line,
const std::string& optName, const std::string& optName,
const Exception& cause): const Exception& cause):
RecoverableException RecoverableException
(file, line, fmt(MESSAGE.c_str(), optName.c_str()), cause), (file, line, fmt(MESSAGE.c_str(), optName.c_str()), error_code::OPTION_ERROR,
cause),
optName_(optName) {} optName_(optName) {}
OptionHandlerException::~OptionHandlerException() throw() {} OptionHandlerException::~OptionHandlerException() throw() {}

View File

@ -49,6 +49,7 @@
#include "array_fun.h" #include "array_fun.h"
#include "OptionHandlerFactory.h" #include "OptionHandlerFactory.h"
#include "DlAbortEx.h" #include "DlAbortEx.h"
#include "error_code.h"
namespace aria2 { namespace aria2 {
@ -158,7 +159,8 @@ void OptionParser::parseArg
op = findByShortName(c); op = findByShortName(c);
} }
if(!op) { if(!op) {
throw DL_ABORT_EX("Failed to parse command-line options."); throw DL_ABORT_EX2("Failed to parse command-line options.",
error_code::OPTION_ERROR);
} }
out << op->getName() << "="; out << op->getName() << "=";
if(optarg) { if(optarg) {

View File

@ -47,6 +47,13 @@ RecoverableException::RecoverableException
: Exception(file, line, msg) : Exception(file, line, msg)
{} {}
RecoverableException::RecoverableException
(const char* file, int line, const std::string& msg,
error_code::Value errorCode,
const Exception& cause)
: Exception(file, line, msg, errorCode, cause)
{}
RecoverableException::RecoverableException RecoverableException::RecoverableException
(const char* file, int line, const std::string& msg, (const char* file, int line, const std::string& msg,
const Exception& cause) const Exception& cause)

View File

@ -44,6 +44,10 @@ protected:
public: public:
RecoverableException(const char* file, int line, const std::string& msg); RecoverableException(const char* file, int line, const std::string& msg);
RecoverableException(const char* file, int line, const std::string& msg,
error_code::Value errorCode,
const Exception& cause);
RecoverableException(const char* file, int line, const std::string& msg, RecoverableException(const char* file, int line, const std::string& msg,
const Exception& cause); const Exception& cause);

View File

@ -44,6 +44,7 @@
#include "message.h" #include "message.h"
#include "DlAbortEx.h" #include "DlAbortEx.h"
#include "A2STR.h" #include "A2STR.h"
#include "error_code.h"
namespace aria2 { namespace aria2 {
@ -200,13 +201,16 @@ MetalinkProcessor::parseFile(const std::string& filename)
int retval = xmlSAXUserParseFile(&mySAXHandler, sessionData.get(), int retval = xmlSAXUserParseFile(&mySAXHandler, sessionData.get(),
nfilename.c_str()); nfilename.c_str());
if(retval != 0) { if(retval != 0) {
throw DL_ABORT_EX(MSG_CANNOT_PARSE_METALINK); throw DL_ABORT_EX2(MSG_CANNOT_PARSE_METALINK,
error_code::METALINK_PARSE_ERROR);
} }
if(!stm_->finished()) { if(!stm_->finished()) {
throw DL_ABORT_EX(MSG_CANNOT_PARSE_METALINK); throw DL_ABORT_EX2(MSG_CANNOT_PARSE_METALINK,
error_code::METALINK_PARSE_ERROR);
} }
if(!stm_->getErrors().empty()) { if(!stm_->getErrors().empty()) {
throw DL_ABORT_EX(stm_->getErrorString()); throw DL_ABORT_EX2(stm_->getErrorString(),
error_code::METALINK_PARSE_ERROR);
} }
return stm_->getResult(); return stm_->getResult();
} }
@ -220,7 +224,8 @@ MetalinkProcessor::parseFromBinaryStream(const SharedHandle<BinaryStream>& binar
ssize_t res = binaryStream->readData(buf, 4, 0); ssize_t res = binaryStream->readData(buf, 4, 0);
if(res != 4) { if(res != 4) {
throw DL_ABORT_EX("Too small data for parsing XML."); throw DL_ABORT_EX2("Too small data for parsing XML.",
error_code::METALINK_PARSE_ERROR);
} }
SharedHandle<SessionData> sessionData(new SessionData(stm_)); SharedHandle<SessionData> sessionData(new SessionData(stm_));
@ -236,17 +241,20 @@ MetalinkProcessor::parseFromBinaryStream(const SharedHandle<BinaryStream>& binar
break; break;
} }
if(xmlParseChunk(ctx, reinterpret_cast<const char*>(buf), res, 0) != 0) { if(xmlParseChunk(ctx, reinterpret_cast<const char*>(buf), res, 0) != 0) {
throw DL_ABORT_EX(MSG_CANNOT_PARSE_METALINK); throw DL_ABORT_EX2(MSG_CANNOT_PARSE_METALINK,
error_code::METALINK_PARSE_ERROR);
} }
readOffset += res; readOffset += res;
} }
xmlParseChunk(ctx, reinterpret_cast<const char*>(buf), 0, 1); xmlParseChunk(ctx, reinterpret_cast<const char*>(buf), 0, 1);
if(!stm_->finished()) { if(!stm_->finished()) {
throw DL_ABORT_EX(MSG_CANNOT_PARSE_METALINK); throw DL_ABORT_EX2(MSG_CANNOT_PARSE_METALINK,
error_code::METALINK_PARSE_ERROR);
} }
if(!stm_->getErrors().empty()) { if(!stm_->getErrors().empty()) {
throw DL_ABORT_EX(stm_->getErrorString()); throw DL_ABORT_EX2(stm_->getErrorString(),
error_code::METALINK_PARSE_ERROR);
} }
return stm_->getResult(); return stm_->getResult();
} }

View File

@ -39,6 +39,7 @@
#include "fmt.h" #include "fmt.h"
#include "DlAbortEx.h" #include "DlAbortEx.h"
#include "error_code.h"
namespace aria2 { namespace aria2 {
@ -53,9 +54,10 @@ void checkdelim(std::istream& ss, const char delim = ':')
{ {
char d; char d;
if(!(ss.get(d) && d == delim)) { if(!(ss.get(d) && d == delim)) {
throw DL_ABORT_EX throw DL_ABORT_EX2
(fmt("Bencode decoding failed: Delimiter '%c' not found.", (fmt("Bencode decoding failed: Delimiter '%c' not found.",
delim)); delim),
error_code::BENCODE_PARSE_ERROR);
} }
} }
} // namespace } // namespace
@ -66,8 +68,9 @@ std::string decoderawstring(std::istream& ss)
int length; int length;
ss >> length; ss >> length;
if(!ss || length < 0) { if(!ss || length < 0) {
throw DL_ABORT_EX("Bencode decoding failed:" throw DL_ABORT_EX2("Bencode decoding failed:"
" A positive integer expected but none found."); " A positive integer expected but none found.",
error_code::BENCODE_PARSE_ERROR);
} }
// TODO check length, it must be less than or equal to INT_MAX // TODO check length, it must be less than or equal to INT_MAX
checkdelim(ss); checkdelim(ss);
@ -76,11 +79,12 @@ std::string decoderawstring(std::istream& ss)
std::string str(&buf[0], &buf[length]); std::string str(&buf[0], &buf[length]);
delete [] buf; delete [] buf;
if(ss.gcount() != static_cast<int>(length)) { if(ss.gcount() != static_cast<int>(length)) {
throw DL_ABORT_EX throw DL_ABORT_EX2
(fmt("Bencode decoding failed:" (fmt("Bencode decoding failed:"
" Expected %lu bytes of data, but only %ld read.", " Expected %lu bytes of data, but only %ld read.",
static_cast<unsigned long>(length), static_cast<unsigned long>(length),
static_cast<long int>(ss.gcount()))); static_cast<long int>(ss.gcount())),
error_code::BENCODE_PARSE_ERROR);
} }
return str; return str;
} }
@ -99,8 +103,9 @@ SharedHandle<ValueBase> decodeinteger(std::istream& ss)
Integer::ValueType iv; Integer::ValueType iv;
ss >> iv; ss >> iv;
if(!ss) { if(!ss) {
throw DL_ABORT_EX("Bencode decoding failed:" throw DL_ABORT_EX2("Bencode decoding failed:"
" Integer expected but none found"); " Integer expected but none found",
error_code::BENCODE_PARSE_ERROR);
} }
checkdelim(ss, 'e'); checkdelim(ss, 'e');
return Integer::g(iv); return Integer::g(iv);
@ -121,8 +126,9 @@ SharedHandle<ValueBase> decodedict(std::istream& ss, size_t depth)
dict->put(key, decodeiter(ss, depth)); dict->put(key, decodeiter(ss, depth));
} }
} }
throw DL_ABORT_EX("Bencode decoding failed:" throw DL_ABORT_EX2("Bencode decoding failed:"
" Unexpected EOF in dict context. 'e' expected."); " Unexpected EOF in dict context. 'e' expected.",
error_code::BENCODE_PARSE_ERROR);
} }
} // namespace } // namespace
@ -139,8 +145,9 @@ SharedHandle<ValueBase> decodelist(std::istream& ss, size_t depth)
list->append(decodeiter(ss, depth)); list->append(decodeiter(ss, depth));
} }
} }
throw DL_ABORT_EX("Bencode decoding failed:" throw DL_ABORT_EX2("Bencode decoding failed:"
" Unexpected EOF in list context. 'e' expected."); " Unexpected EOF in list context. 'e' expected.",
error_code::BENCODE_PARSE_ERROR);
} }
} // namespace } // namespace
@ -148,7 +155,8 @@ namespace {
void checkDepth(size_t depth) void checkDepth(size_t depth)
{ {
if(depth >= MAX_STRUCTURE_DEPTH) { if(depth >= MAX_STRUCTURE_DEPTH) {
throw DL_ABORT_EX("Bencode decoding failed: Structure is too deep."); throw DL_ABORT_EX2("Bencode decoding failed: Structure is too deep.",
error_code::BENCODE_PARSE_ERROR);
} }
} }
} // namespace } // namespace
@ -159,9 +167,10 @@ SharedHandle<ValueBase> decodeiter(std::istream& ss, size_t depth)
checkDepth(depth); checkDepth(depth);
char c; char c;
if(!ss.get(c)) { if(!ss.get(c)) {
throw DL_ABORT_EX("Bencode decoding failed:" throw DL_ABORT_EX2("Bencode decoding failed:"
" Unexpected EOF in term context." " Unexpected EOF in term context."
" 'd', 'l', 'i' or digit is expected."); " 'd', 'l', 'i' or digit is expected.",
error_code::BENCODE_PARSE_ERROR);
} }
if(c == 'd') { if(c == 'd') {
return decodedict(ss, depth+1); return decodedict(ss, depth+1);
@ -215,9 +224,10 @@ SharedHandle<ValueBase> decodeFromFile(const std::string& filename)
if(f) { if(f) {
return decode(f); return decode(f);
} else { } else {
throw DL_ABORT_EX throw DL_ABORT_EX2
(fmt("Bencode decoding failed: Cannot open file '%s'.", (fmt("Bencode decoding failed: Cannot open file '%s'.",
filename.c_str())); filename.c_str()),
error_code::BENCODE_PARSE_ERROR);
} }
} }

View File

@ -58,6 +58,7 @@
#include "Option.h" #include "Option.h"
#include "prefs.h" #include "prefs.h"
#include "FileEntry.h" #include "FileEntry.h"
#include "error_code.h"
namespace aria2 { namespace aria2 {
@ -209,9 +210,10 @@ void extractFileEntries
if(nameData) { if(nameData) {
utf8Name = util::encodeNonUtf8(nameData->s()); utf8Name = util::encodeNonUtf8(nameData->s());
if(util::detectDirTraversal(utf8Name)) { if(util::detectDirTraversal(utf8Name)) {
throw DL_ABORT_EX throw DL_ABORT_EX2
(fmt(MSG_DIR_TRAVERSAL_DETECTED, (fmt(MSG_DIR_TRAVERSAL_DETECTED,
nameData->s().c_str())); nameData->s().c_str()),
error_code::BITTORRENT_PARSE_ERROR);
} }
name = nameData->s(); name = nameData->s();
} else { } else {
@ -237,7 +239,8 @@ void extractFileEntries
} }
const Integer* fileLengthData = asInteger(fileDict->get(C_LENGTH)); const Integer* fileLengthData = asInteger(fileDict->get(C_LENGTH));
if(!fileLengthData) { if(!fileLengthData) {
throw DL_ABORT_EX(fmt(MSG_MISSING_BT_INFO, C_LENGTH.c_str())); throw DL_ABORT_EX2(fmt(MSG_MISSING_BT_INFO, C_LENGTH.c_str()),
error_code::BITTORRENT_PARSE_ERROR);
} }
length += fileLengthData->i(); length += fileLengthData->i();
@ -249,7 +252,8 @@ void extractFileEntries
} }
const List* pathList = asList(fileDict->get(pathKey)); const List* pathList = asList(fileDict->get(pathKey));
if(!pathList || pathList->empty()) { if(!pathList || pathList->empty()) {
throw DL_ABORT_EX("Path is empty."); throw DL_ABORT_EX2("Path is empty.",
error_code::BITTORRENT_PARSE_ERROR);
} }
std::vector<std::string> pathelem(pathList->size()+1); std::vector<std::string> pathelem(pathList->size()+1);
@ -262,14 +266,16 @@ void extractFileEntries
if(elem) { if(elem) {
(*pathelemOutItr++) = elem->s(); (*pathelemOutItr++) = elem->s();
} else { } else {
throw DL_ABORT_EX("Path element is not string."); throw DL_ABORT_EX2("Path element is not string.",
error_code::BITTORRENT_PARSE_ERROR);
} }
} }
std::string path = strjoin(pathelem.begin(), pathelem.end(), '/'); std::string path = strjoin(pathelem.begin(), pathelem.end(), '/');
std::string utf8Path = strjoin(pathelem.begin(), pathelem.end(), '/', std::string utf8Path = strjoin(pathelem.begin(), pathelem.end(), '/',
std::ptr_fun(util::encodeNonUtf8)); std::ptr_fun(util::encodeNonUtf8));
if(util::detectDirTraversal(utf8Path)) { if(util::detectDirTraversal(utf8Path)) {
throw DL_ABORT_EX(fmt(MSG_DIR_TRAVERSAL_DETECTED, utf8Path.c_str())); throw DL_ABORT_EX2(fmt(MSG_DIR_TRAVERSAL_DETECTED, utf8Path.c_str()),
error_code::BITTORRENT_PARSE_ERROR);
} }
std::string pePath = std::string pePath =
strjoin(pathelem.begin(), pathelem.end(), '/', strjoin(pathelem.begin(), pathelem.end(), '/',
@ -289,7 +295,8 @@ void extractFileEntries
torrent->mode = SINGLE; torrent->mode = SINGLE;
const Integer* lengthData = asInteger(infoDict->get(C_LENGTH)); const Integer* lengthData = asInteger(infoDict->get(C_LENGTH));
if(!lengthData) { if(!lengthData) {
throw DL_ABORT_EX(fmt(MSG_MISSING_BT_INFO, C_LENGTH.c_str())); throw DL_ABORT_EX2(fmt(MSG_MISSING_BT_INFO, C_LENGTH.c_str()),
error_code::BITTORRENT_PARSE_ERROR);
} }
uint64_t totalLength = lengthData->i(); uint64_t totalLength = lengthData->i();
@ -391,11 +398,13 @@ void processRootDictionary
{ {
const Dict* rootDict = asDict(root); const Dict* rootDict = asDict(root);
if(!rootDict) { if(!rootDict) {
throw DL_ABORT_EX("torrent file does not contain a root dictionary."); throw DL_ABORT_EX2("torrent file does not contain a root dictionary.",
error_code::BITTORRENT_PARSE_ERROR);
} }
const Dict* infoDict = asDict(rootDict->get(C_INFO)); const Dict* infoDict = asDict(rootDict->get(C_INFO));
if(!infoDict) { if(!infoDict) {
throw DL_ABORT_EX(fmt(MSG_MISSING_BT_INFO, C_INFO.c_str())); throw DL_ABORT_EX2(fmt(MSG_MISSING_BT_INFO, C_INFO.c_str()),
error_code::BITTORRENT_PARSE_ERROR);
} }
SharedHandle<TorrentAttribute> torrent(new TorrentAttribute()); SharedHandle<TorrentAttribute> torrent(new TorrentAttribute());
@ -413,7 +422,8 @@ void processRootDictionary
// calculate the number of pieces // calculate the number of pieces
const String* piecesData = asString(infoDict->get(C_PIECES)); const String* piecesData = asString(infoDict->get(C_PIECES));
if(!piecesData) { if(!piecesData) {
throw DL_ABORT_EX(fmt(MSG_MISSING_BT_INFO, C_PIECES.c_str())); throw DL_ABORT_EX2(fmt(MSG_MISSING_BT_INFO, C_PIECES.c_str()),
error_code::BITTORRENT_PARSE_ERROR);
} }
// Commented out To download 0 length torrent. // Commented out To download 0 length torrent.
// if(piecesData.s().empty()) { // if(piecesData.s().empty()) {
@ -427,7 +437,8 @@ void processRootDictionary
// retrieve piece length // retrieve piece length
const Integer* pieceLengthData = asInteger(infoDict->get(C_PIECE_LENGTH)); const Integer* pieceLengthData = asInteger(infoDict->get(C_PIECE_LENGTH));
if(!pieceLengthData) { if(!pieceLengthData) {
throw DL_ABORT_EX(fmt(MSG_MISSING_BT_INFO, C_PIECE_LENGTH.c_str())); throw DL_ABORT_EX2(fmt(MSG_MISSING_BT_INFO, C_PIECE_LENGTH.c_str()),
error_code::BITTORRENT_PARSE_ERROR);
} }
size_t pieceLength = pieceLengthData->i(); size_t pieceLength = pieceLengthData->i();
ctx->setPieceLength(pieceLength); ctx->setPieceLength(pieceLength);
@ -457,7 +468,8 @@ void processRootDictionary
extractFileEntries extractFileEntries
(ctx, torrent, infoDict, defaultName, overrideName, urlList); (ctx, torrent, infoDict, defaultName, overrideName, urlList);
if((ctx->getTotalLength()+pieceLength-1)/pieceLength != numPieces) { if((ctx->getTotalLength()+pieceLength-1)/pieceLength != numPieces) {
throw DL_ABORT_EX("Too few/many piece hash."); throw DL_ABORT_EX2("Too few/many piece hash.",
error_code::BITTORRENT_PARSE_ERROR);
} }
// retrieve announce // retrieve announce
extractAnnounce(torrent, rootDict); extractAnnounce(torrent, rootDict);
@ -908,11 +920,13 @@ SharedHandle<TorrentAttribute> parseMagnet(const std::string& magnet)
{ {
SharedHandle<Dict> r = magnet::parse(magnet); SharedHandle<Dict> r = magnet::parse(magnet);
if(!r) { if(!r) {
throw DL_ABORT_EX("Bad BitTorrent Magnet URI."); throw DL_ABORT_EX2("Bad BitTorrent Magnet URI.",
error_code::MAGNET_PARSE_ERROR);
} }
const List* xts = asList(r->get("xt")); const List* xts = asList(r->get("xt"));
if(!xts) { if(!xts) {
throw DL_ABORT_EX("Missing xt parameter in Magnet URI."); throw DL_ABORT_EX2("Missing xt parameter in Magnet URI.",
error_code::MAGNET_PARSE_ERROR);
} }
SharedHandle<TorrentAttribute> attrs(new TorrentAttribute()); SharedHandle<TorrentAttribute> attrs(new TorrentAttribute());
std::string infoHash; std::string infoHash;
@ -936,8 +950,9 @@ SharedHandle<TorrentAttribute> parseMagnet(const std::string& magnet)
} }
} }
if(infoHash.empty()) { if(infoHash.empty()) {
throw DL_ABORT_EX("Bad BitTorrent Magnet URI. " throw DL_ABORT_EX2("Bad BitTorrent Magnet URI. "
"No valid BitTorrent Info Hash found."); "No valid BitTorrent Info Hash found.",
error_code::MAGNET_PARSE_ERROR);
} }
const List* trs = asList(r->get("tr")); const List* trs = asList(r->get("tr"));
if(trs) { if(trs) {

View File

@ -57,7 +57,21 @@ enum Value {
DUPLICATE_DOWNLOAD = 11, DUPLICATE_DOWNLOAD = 11,
DUPLICATE_INFO_HASH = 12, DUPLICATE_INFO_HASH = 12,
FILE_ALREADY_EXISTS = 13, FILE_ALREADY_EXISTS = 13,
FILE_RENAMING_FAILED = 14 FILE_RENAMING_FAILED = 14,
FILE_OPEN_ERROR = 15,
FILE_CREATE_ERROR = 16,
FILE_IO_ERROR = 17,
DIR_CREATE_ERROR = 18,
NAME_RESOLVE_ERROR = 19,
METALINK_PARSE_ERROR = 20,
FTP_PROTOCOL_ERROR = 21,
HTTP_PROTOCOL_ERROR = 22,
HTTP_TOO_MANY_REDIRECTS = 23,
HTTP_AUTH_FAILED = 24,
BENCODE_PARSE_ERROR = 25,
BITTORRENT_PARSE_ERROR = 26,
MAGNET_PARSE_ERROR = 27,
OPTION_ERROR = 28
}; };
} // namespace error_code } // namespace error_code

View File

@ -145,11 +145,11 @@ void option_processing(Option& op, std::vector<std::string>& uris,
<< oparser.findByName(e.getOptionName())->getDescription() << oparser.findByName(e.getOptionName())->getDescription()
<< std::endl; << std::endl;
} }
exit(error_code::UNKNOWN_ERROR); exit(e.getErrorCode());
} catch(Exception& e) { } catch(Exception& e) {
std::cerr << "Parse error in " << cfname << "\n" std::cerr << "Parse error in " << cfname << "\n"
<< e.stackTrace() << std::endl; << e.stackTrace() << std::endl;
exit(error_code::UNKNOWN_ERROR); exit(e.getErrorCode());
} }
} else if(!ucfname.empty()) { } else if(!ucfname.empty()) {
std::cerr << fmt("Configuration file %s is not found.", cfname.c_str()) std::cerr << fmt("Configuration file %s is not found.", cfname.c_str())
@ -171,15 +171,18 @@ void option_processing(Option& op, std::vector<std::string>& uris,
// finaly let's parse and store command-iine options. // finaly let's parse and store command-iine options.
oparser.parse(op, cmdstream); oparser.parse(op, cmdstream);
} catch(OptionHandlerException& e) { } catch(OptionHandlerException& e) {
std::cerr << e.stackTrace() << "\n" std::cerr << e.stackTrace() << "\n";
<< "Usage:" << "\n" SharedHandle<OptionHandler> h = oparser.findByName(e.getOptionName());
<< *oparser.findByName(e.getOptionName()) if(h) {
std::cerr << "Usage:" << "\n"
<< *h
<< std::endl; << std::endl;
exit(error_code::UNKNOWN_ERROR); }
exit(e.getErrorCode());
} catch(Exception& e) { } catch(Exception& e) {
std::cerr << e.stackTrace() << std::endl; std::cerr << e.stackTrace() << std::endl;
showUsage(TAG_HELP, oparser); showUsage(TAG_HELP, oparser);
exit(error_code::UNKNOWN_ERROR); exit(e.getErrorCode());
} }
if( if(
#ifdef ENABLE_XML_RPC #ifdef ENABLE_XML_RPC

View File

@ -1151,9 +1151,11 @@ void mkdirs(const std::string& dirpath)
if(!dir.mkdirs()) { if(!dir.mkdirs()) {
int errNum = errno; int errNum = errno;
if(!dir.isDir()) { if(!dir.isDir()) {
throw DL_ABORT_EX throw DL_ABORT_EX3
(fmt(EX_MAKE_DIR, dir.getPath().c_str(), (errNum,
safeStrerror(errNum).c_str())); fmt(EX_MAKE_DIR, dir.getPath().c_str(),
safeStrerror(errNum).c_str()),
error_code::DIR_CREATE_ERROR);
} }
} }
} }