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

View File

@ -51,6 +51,7 @@
#include "a2io.h"
#include "fmt.h"
#include "DownloadFailureException.h"
#include "error_code.h"
namespace aria2 {
@ -100,10 +101,12 @@ void AbstractDiskWriter::openExistingFile(uint64_t totalLength)
errno == EINTR);
if(fd_ < 0) {
int errNum = errno;
throw DL_ABORT_EX2
(errNum, fmt(EX_FILE_OPEN,
filename_.c_str(),
util::safeStrerror(errNum).c_str()));
throw DL_ABORT_EX3
(errNum,
fmt(EX_FILE_OPEN,
filename_.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);
if(fd_ < 0) {
int errNum = errno;
throw DL_ABORT_EX2
(errNum, fmt(EX_FILE_OPEN,
filename_.c_str(),
util::safeStrerror(errNum).c_str()));
throw DL_ABORT_EX3
(errNum,
fmt(EX_FILE_OPEN,
filename_.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) {
int errNum = errno;
throw DL_ABORT_EX(fmt(EX_FILE_SEEK,
filename_.c_str(),
util::safeStrerror(errNum).c_str()));
throw DL_ABORT_EX2(fmt(EX_FILE_SEEK,
filename_.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
// DownloadFailureException and abort download instantly.
if(errNum == ENOSPC) {
throw DOWNLOAD_FAILURE_EXCEPTION2
(fmt(EX_FILE_WRITE,
throw DOWNLOAD_FAILURE_EXCEPTION3
(errNum,
fmt(EX_FILE_WRITE,
filename_.c_str(),
util::safeStrerror(errNum).c_str()),
error_code::NOT_ENOUGH_DISK_SPACE);
} else {
throw DL_ABORT_EX
(fmt(EX_FILE_WRITE,
throw DL_ABORT_EX3
(errNum,
fmt(EX_FILE_WRITE,
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);
if((ret = readDataInternal(data, len)) < 0) {
int errNum = errno;
throw DL_ABORT_EX
(fmt(EX_FILE_READ,
throw DL_ABORT_EX3
(errNum,
fmt(EX_FILE_READ,
filename_.c_str(),
util::safeStrerror(errNum).c_str()));
util::safeStrerror(errNum).c_str()),
error_code::FILE_IO_ERROR);
}
return ret;
}
@ -201,14 +212,17 @@ void AbstractDiskWriter::truncate(uint64_t length)
HANDLE handle = LongToHandle(_get_osfhandle(fd_));
seek(length);
if(SetEndOfFile(handle) == 0) {
throw DL_ABORT_EX(fmt("SetEndOfFile failed. cause: %s",
GetLastError()));
throw DL_ABORT_EX2(fmt("SetEndOfFile failed. cause: %s",
GetLastError()),
error_code::FILE_IO_ERROR);
}
#else
if(ftruncate(fd_, length) == -1) {
int errNum = errno;
throw DL_ABORT_EX(fmt("ftruncate failed. cause: %s",
util::safeStrerror(errNum).c_str()));
throw DL_ABORT_EX3(errNum,
fmt("ftruncate failed. cause: %s",
util::safeStrerror(errNum).c_str()),
error_code::FILE_IO_ERROR);
}
#endif
}
@ -226,14 +240,18 @@ void AbstractDiskWriter::allocate(off_t offset, uint64_t length)
while((r = fallocate(fd_, 0, offset, length)) == -1 && errno == EINTR);
int errNum = errno;
if(r == -1) {
throw DL_ABORT_EX(fmt("fallocate failed. cause: %s",
util::safeStrerror(errNum).c_str()));
throw DL_ABORT_EX3(errNum,
fmt("fallocate failed. cause: %s",
util::safeStrerror(errNum).c_str()),
error_code::FILE_IO_ERROR);
}
# elif HAVE_POSIX_FALLOCATE
int r = posix_fallocate(fd_, offset, length);
if(r != 0) {
throw DL_ABORT_EX(fmt("posix_fallocate failed. cause: %s",
util::safeStrerror(r).c_str()));
throw DL_ABORT_EX3(errNum,
fmt("posix_fallocate failed. cause: %s",
util::safeStrerror(r).c_str()),
error_code::FILE_IO_ERROR);
}
# else
# error "no *_fallocate function available."

View File

@ -58,7 +58,7 @@ public:
#define DL_ABORT_EX(arg) DlAbortEx(__FILE__, __LINE__, arg)
#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)
} // namespace aria2

View File

@ -57,4 +57,11 @@ DownloadFailureException::DownloadFailureException
error_code::Value 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

View File

@ -54,12 +54,19 @@ public:
DownloadFailureException(const char* file, int line,
const std::string& msg,
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) \
DownloadFailureException(__FILE__, __LINE__, arg)
#define DOWNLOAD_FAILURE_EXCEPTION2(arg1, arg2) \
DownloadFailureException(__FILE__, __LINE__, arg1, arg2)
#define DOWNLOAD_FAILURE_EXCEPTION3(arg1, arg2, arg3) \
DownloadFailureException(__FILE__, __LINE__, arg1, arg2, arg3)
} // namespace aria2

View File

@ -53,13 +53,27 @@ Exception::Exception
(const char* file,
int line,
const std::string& msg,
error_code::Value errorCode,
const Exception& cause)
: file_(file),
line_(line),
errNum_(0),
msg_(msg),
cause_(cause.copy()),
errorCode_(cause.errorCode_)
errorCode_(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

View File

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

View File

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

View File

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

View File

@ -72,6 +72,7 @@
#include "HttpResponse.h"
#include "DlRetryEx.h"
#include "CheckIntegrityEntry.h"
#include "error_code.h"
namespace aria2 {
@ -154,7 +155,7 @@ bool FtpNegotiationCommand::recvGreeting() {
return false;
}
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;
@ -183,7 +184,8 @@ bool FtpNegotiationCommand::recvUser() {
sequence_ = SEQ_SEND_PASS;
break;
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;
}
@ -204,7 +206,8 @@ bool FtpNegotiationCommand::recvPass() {
return false;
}
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;
return true;
@ -226,7 +229,8 @@ bool FtpNegotiationCommand::recvType() {
return false;
}
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;
return true;
@ -251,7 +255,8 @@ bool FtpNegotiationCommand::recvPwd()
return false;
}
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);
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,
error_code::RESOURCE_NOT_FOUND);
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();
if(cwdDirs_.empty()) {
@ -461,9 +467,10 @@ bool FtpNegotiationCommand::recvSize() {
if(status == 213) {
if(size > INT64_MAX) {
throw DL_ABORT_EX
throw DL_ABORT_EX2
(fmt(EX_TOO_LARGE_FILE,
util::uitos(size, true).c_str()));
util::uitos(size, true).c_str()),
error_code::FTP_PROTOCOL_ERROR);
}
if(!getPieceStorage()) {
@ -563,7 +570,8 @@ bool FtpNegotiationCommand::recvPort() {
return false;
}
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;
return true;
@ -624,7 +632,8 @@ bool FtpNegotiationCommand::recvPasv() {
return false;
}
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;
@ -744,8 +753,9 @@ bool FtpNegotiationCommand::sendRestPasv(const SharedHandle<Segment>& segment) {
// Check connection is made properly
if(dataSocket_->isReadable(0)) {
std::string error = dataSocket_->getSocketError();
throw DL_ABORT_EX
(fmt(MSG_ESTABLISHING_CONNECTION_FAILED, error.c_str()));
throw DL_ABORT_EX2
(fmt(MSG_ESTABLISHING_CONNECTION_FAILED, error.c_str()),
error_code::FTP_PROTOCOL_ERROR);
}
setReadCheckSocket(getSocket());
disableWriteCheckSocket();
@ -800,7 +810,8 @@ bool FtpNegotiationCommand::recvRetr() {
throw DL_ABORT_EX2(MSG_RESOURCE_NOT_FOUND,
error_code::RESOURCE_NOT_FOUND);
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)) {
sequence_ = SEQ_NEGOTIATION_COMPLETED;

View File

@ -43,6 +43,7 @@
#include "DlRetryEx.h"
#include "DlAbortEx.h"
#include "A2STR.h"
#include "error_code.h"
namespace aria2 {
@ -71,7 +72,8 @@ void HttpHeaderProcessor::update(const std::string& data)
void HttpHeaderProcessor::checkHeaderLimit(size_t incomingLength)
{
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;
util::split(buf_.substr(0, delimpos), std::back_inserter(firstLine)," ",true);
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());
httpHeader->setMethod(firstLine[0]);

View File

@ -50,6 +50,7 @@
#include "AuthConfigFactory.h"
#include "AuthConfig.h"
#include "ChunkedDecodingStreamFilter.h"
#include "error_code.h"
#ifdef HAVE_LIBZ
# include "GZipDecodingStreamFilter.h"
#endif // HAVE_LIBZ
@ -70,14 +71,16 @@ void HttpResponse::validateResponse() const
}
if(statusCode == 304) {
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 ||
statusCode == 302 ||
statusCode == 303 ||
statusCode == 307) {
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;
} else if(statusCode == 200 || statusCode == 206) {
@ -97,7 +100,8 @@ void HttpResponse::validateResponse() const
}
}
} 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 "NullSinkStreamFilter.h"
#include "SinkStreamFilter.h"
#include "error_code.h"
namespace aria2 {
@ -175,7 +176,8 @@ bool HttpSkipResponseCommand::processResponse()
unsigned int rnum =
httpResponse_->getHttpRequest()->getRequest()->getRedirectCount();
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();
return prepareForRetry(0);
@ -187,13 +189,15 @@ bool HttpSkipResponseCommand::processResponse()
(getRequest()->getHost(), getRequest()->getDir(), getOption().get())) {
return prepareForRetry(0);
} else {
throw DL_ABORT_EX(EX_AUTH_FAILED);
throw DL_ABORT_EX2(EX_AUTH_FAILED,
error_code::HTTP_AUTH_FAILED);
}
} else if(statusCode == 404) {
throw DL_ABORT_EX2(MSG_RESOURCE_NOT_FOUND,
error_code::RESOURCE_NOT_FOUND);
} 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 {
return prepareForRetry(0);

View File

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

View File

@ -43,14 +43,15 @@ const std::string OptionHandlerException::MESSAGE
OptionHandlerException::OptionHandlerException(const char* file, int line,
const std::string& optName):
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) {}
OptionHandlerException::OptionHandlerException(const char* file, int line,
const std::string& optName,
const Exception& cause):
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) {}
OptionHandlerException::~OptionHandlerException() throw() {}

View File

@ -49,6 +49,7 @@
#include "array_fun.h"
#include "OptionHandlerFactory.h"
#include "DlAbortEx.h"
#include "error_code.h"
namespace aria2 {
@ -158,7 +159,8 @@ void OptionParser::parseArg
op = findByShortName(c);
}
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() << "=";
if(optarg) {

View File

@ -47,6 +47,13 @@ RecoverableException::RecoverableException
: 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
(const char* file, int line, const std::string& msg,
const Exception& cause)

View File

@ -44,6 +44,10 @@ protected:
public:
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,
const Exception& cause);

View File

@ -44,6 +44,7 @@
#include "message.h"
#include "DlAbortEx.h"
#include "A2STR.h"
#include "error_code.h"
namespace aria2 {
@ -200,13 +201,16 @@ MetalinkProcessor::parseFile(const std::string& filename)
int retval = xmlSAXUserParseFile(&mySAXHandler, sessionData.get(),
nfilename.c_str());
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()) {
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()) {
throw DL_ABORT_EX(stm_->getErrorString());
throw DL_ABORT_EX2(stm_->getErrorString(),
error_code::METALINK_PARSE_ERROR);
}
return stm_->getResult();
}
@ -220,7 +224,8 @@ MetalinkProcessor::parseFromBinaryStream(const SharedHandle<BinaryStream>& binar
ssize_t res = binaryStream->readData(buf, 4, 0);
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_));
@ -236,17 +241,20 @@ MetalinkProcessor::parseFromBinaryStream(const SharedHandle<BinaryStream>& binar
break;
}
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;
}
xmlParseChunk(ctx, reinterpret_cast<const char*>(buf), 0, 1);
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()) {
throw DL_ABORT_EX(stm_->getErrorString());
throw DL_ABORT_EX2(stm_->getErrorString(),
error_code::METALINK_PARSE_ERROR);
}
return stm_->getResult();
}

View File

@ -39,6 +39,7 @@
#include "fmt.h"
#include "DlAbortEx.h"
#include "error_code.h"
namespace aria2 {
@ -53,9 +54,10 @@ void checkdelim(std::istream& ss, const char delim = ':')
{
char d;
if(!(ss.get(d) && d == delim)) {
throw DL_ABORT_EX
throw DL_ABORT_EX2
(fmt("Bencode decoding failed: Delimiter '%c' not found.",
delim));
delim),
error_code::BENCODE_PARSE_ERROR);
}
}
} // namespace
@ -66,8 +68,9 @@ std::string decoderawstring(std::istream& ss)
int length;
ss >> length;
if(!ss || length < 0) {
throw DL_ABORT_EX("Bencode decoding failed:"
" A positive integer expected but none found.");
throw DL_ABORT_EX2("Bencode decoding failed:"
" 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
checkdelim(ss);
@ -76,11 +79,12 @@ std::string decoderawstring(std::istream& ss)
std::string str(&buf[0], &buf[length]);
delete [] buf;
if(ss.gcount() != static_cast<int>(length)) {
throw DL_ABORT_EX
throw DL_ABORT_EX2
(fmt("Bencode decoding failed:"
" Expected %lu bytes of data, but only %ld read.",
static_cast<unsigned long>(length),
static_cast<long int>(ss.gcount())));
static_cast<long int>(ss.gcount())),
error_code::BENCODE_PARSE_ERROR);
}
return str;
}
@ -99,8 +103,9 @@ SharedHandle<ValueBase> decodeinteger(std::istream& ss)
Integer::ValueType iv;
ss >> iv;
if(!ss) {
throw DL_ABORT_EX("Bencode decoding failed:"
" Integer expected but none found");
throw DL_ABORT_EX2("Bencode decoding failed:"
" Integer expected but none found",
error_code::BENCODE_PARSE_ERROR);
}
checkdelim(ss, 'e');
return Integer::g(iv);
@ -121,8 +126,9 @@ SharedHandle<ValueBase> decodedict(std::istream& ss, size_t depth)
dict->put(key, decodeiter(ss, depth));
}
}
throw DL_ABORT_EX("Bencode decoding failed:"
" Unexpected EOF in dict context. 'e' expected.");
throw DL_ABORT_EX2("Bencode decoding failed:"
" Unexpected EOF in dict context. 'e' expected.",
error_code::BENCODE_PARSE_ERROR);
}
} // namespace
@ -139,8 +145,9 @@ SharedHandle<ValueBase> decodelist(std::istream& ss, size_t depth)
list->append(decodeiter(ss, depth));
}
}
throw DL_ABORT_EX("Bencode decoding failed:"
" Unexpected EOF in list context. 'e' expected.");
throw DL_ABORT_EX2("Bencode decoding failed:"
" Unexpected EOF in list context. 'e' expected.",
error_code::BENCODE_PARSE_ERROR);
}
} // namespace
@ -148,7 +155,8 @@ namespace {
void checkDepth(size_t 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
@ -159,9 +167,10 @@ SharedHandle<ValueBase> decodeiter(std::istream& ss, size_t depth)
checkDepth(depth);
char c;
if(!ss.get(c)) {
throw DL_ABORT_EX("Bencode decoding failed:"
" Unexpected EOF in term context."
" 'd', 'l', 'i' or digit is expected.");
throw DL_ABORT_EX2("Bencode decoding failed:"
" Unexpected EOF in term context."
" 'd', 'l', 'i' or digit is expected.",
error_code::BENCODE_PARSE_ERROR);
}
if(c == 'd') {
return decodedict(ss, depth+1);
@ -215,9 +224,10 @@ SharedHandle<ValueBase> decodeFromFile(const std::string& filename)
if(f) {
return decode(f);
} else {
throw DL_ABORT_EX
throw DL_ABORT_EX2
(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 "prefs.h"
#include "FileEntry.h"
#include "error_code.h"
namespace aria2 {
@ -209,9 +210,10 @@ void extractFileEntries
if(nameData) {
utf8Name = util::encodeNonUtf8(nameData->s());
if(util::detectDirTraversal(utf8Name)) {
throw DL_ABORT_EX
throw DL_ABORT_EX2
(fmt(MSG_DIR_TRAVERSAL_DETECTED,
nameData->s().c_str()));
nameData->s().c_str()),
error_code::BITTORRENT_PARSE_ERROR);
}
name = nameData->s();
} else {
@ -237,7 +239,8 @@ void extractFileEntries
}
const Integer* fileLengthData = asInteger(fileDict->get(C_LENGTH));
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();
@ -249,7 +252,8 @@ void extractFileEntries
}
const List* pathList = asList(fileDict->get(pathKey));
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);
@ -262,14 +266,16 @@ void extractFileEntries
if(elem) {
(*pathelemOutItr++) = elem->s();
} 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 utf8Path = strjoin(pathelem.begin(), pathelem.end(), '/',
std::ptr_fun(util::encodeNonUtf8));
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 =
strjoin(pathelem.begin(), pathelem.end(), '/',
@ -289,7 +295,8 @@ void extractFileEntries
torrent->mode = SINGLE;
const Integer* lengthData = asInteger(infoDict->get(C_LENGTH));
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();
@ -391,11 +398,13 @@ void processRootDictionary
{
const Dict* rootDict = asDict(root);
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));
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());
@ -413,7 +422,8 @@ void processRootDictionary
// calculate the number of pieces
const String* piecesData = asString(infoDict->get(C_PIECES));
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.
// if(piecesData.s().empty()) {
@ -427,7 +437,8 @@ void processRootDictionary
// retrieve piece length
const Integer* pieceLengthData = asInteger(infoDict->get(C_PIECE_LENGTH));
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();
ctx->setPieceLength(pieceLength);
@ -457,7 +468,8 @@ void processRootDictionary
extractFileEntries
(ctx, torrent, infoDict, defaultName, overrideName, urlList);
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
extractAnnounce(torrent, rootDict);
@ -908,11 +920,13 @@ SharedHandle<TorrentAttribute> parseMagnet(const std::string& magnet)
{
SharedHandle<Dict> r = magnet::parse(magnet);
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"));
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());
std::string infoHash;
@ -936,8 +950,9 @@ SharedHandle<TorrentAttribute> parseMagnet(const std::string& magnet)
}
}
if(infoHash.empty()) {
throw DL_ABORT_EX("Bad BitTorrent Magnet URI. "
"No valid BitTorrent Info Hash found.");
throw DL_ABORT_EX2("Bad BitTorrent Magnet URI. "
"No valid BitTorrent Info Hash found.",
error_code::MAGNET_PARSE_ERROR);
}
const List* trs = asList(r->get("tr"));
if(trs) {

View File

@ -57,7 +57,21 @@ enum Value {
DUPLICATE_DOWNLOAD = 11,
DUPLICATE_INFO_HASH = 12,
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

View File

@ -145,11 +145,11 @@ void option_processing(Option& op, std::vector<std::string>& uris,
<< oparser.findByName(e.getOptionName())->getDescription()
<< std::endl;
}
exit(error_code::UNKNOWN_ERROR);
exit(e.getErrorCode());
} catch(Exception& e) {
std::cerr << "Parse error in " << cfname << "\n"
<< e.stackTrace() << std::endl;
exit(error_code::UNKNOWN_ERROR);
exit(e.getErrorCode());
}
} else if(!ucfname.empty()) {
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.
oparser.parse(op, cmdstream);
} catch(OptionHandlerException& e) {
std::cerr << e.stackTrace() << "\n"
<< "Usage:" << "\n"
<< *oparser.findByName(e.getOptionName())
<< std::endl;
exit(error_code::UNKNOWN_ERROR);
std::cerr << e.stackTrace() << "\n";
SharedHandle<OptionHandler> h = oparser.findByName(e.getOptionName());
if(h) {
std::cerr << "Usage:" << "\n"
<< *h
<< std::endl;
}
exit(e.getErrorCode());
} catch(Exception& e) {
std::cerr << e.stackTrace() << std::endl;
showUsage(TAG_HELP, oparser);
exit(error_code::UNKNOWN_ERROR);
exit(e.getErrorCode());
}
if(
#ifdef ENABLE_XML_RPC

View File

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