diff --git a/doc/manual-src/en/aria2c.rst b/doc/manual-src/en/aria2c.rst index a830fbf3..a75cb7be 100644 --- a/doc/manual-src/en/aria2c.rst +++ b/doc/manual-src/en/aria2c.rst @@ -2492,6 +2492,10 @@ For information on the *secret* parameter, see :ref:`rpc_auth`. is a string. The error codes are defined in the `EXIT STATUS`_ section. This value is only available for stopped/completed downloads. + ``errorMessage`` + The (hopefully) human readable error message associated to + ``errorCode``. + ``followedBy`` List of GIDs which are generated as the result of this download. For example, when aria2 downloads a Metalink file, it diff --git a/src/AbstractCommand.cc b/src/AbstractCommand.cc index 687e7881..59b92c06 100644 --- a/src/AbstractCommand.cc +++ b/src/AbstractCommand.cc @@ -343,7 +343,7 @@ bool AbstractCommand::execute() return false; } catch (DlAbortEx& err) { - requestGroup_->setLastErrorCode(err.getErrorCode()); + requestGroup_->setLastErrorCode(err.getErrorCode(), err.what()); if (req_) { A2_LOG_ERROR_EX (fmt(MSG_DOWNLOAD_ABORTED, getCuid(), req_->getUri().c_str()), @@ -376,7 +376,7 @@ bool AbstractCommand::execute() A2_LOG_ERROR_EX (fmt(MSG_DOWNLOAD_ABORTED, getCuid(), req_->getUri().c_str()), err); fileEntry_->addURIResult(req_->getUri(), err.getErrorCode()); - requestGroup_->setLastErrorCode(err.getErrorCode()); + requestGroup_->setLastErrorCode(err.getErrorCode(), err.what()); if (err.getErrorCode() == error_code::CANNOT_RESUME) { requestGroup_->increaseResumeFailureCount(); } @@ -392,7 +392,7 @@ bool AbstractCommand::execute() return prepareForRetry(0); } catch (DownloadFailureException& err) { - requestGroup_->setLastErrorCode(err.getErrorCode()); + requestGroup_->setLastErrorCode(err.getErrorCode(), err.what()); if (req_) { A2_LOG_ERROR_EX (fmt(MSG_DOWNLOAD_ABORTED, getCuid(), req_->getUri().c_str()), diff --git a/src/DownloadResult.h b/src/DownloadResult.h index 37fc3919..527da3c0 100644 --- a/src/DownloadResult.h +++ b/src/DownloadResult.h @@ -92,6 +92,8 @@ struct DownloadResult error_code::Value result; + std::string resultMessage; + bool inMemoryDownload; DownloadResult(); diff --git a/src/PeerInteractionCommand.cc b/src/PeerInteractionCommand.cc index a7deb295..e3731c37 100644 --- a/src/PeerInteractionCommand.cc +++ b/src/PeerInteractionCommand.cc @@ -402,7 +402,7 @@ void PeerInteractionCommand::onAbort() { void PeerInteractionCommand::onFailure(const Exception& err) { - requestGroup_->setLastErrorCode(err.getErrorCode()); + requestGroup_->setLastErrorCode(err.getErrorCode(), err.what()); requestGroup_->setHaltRequested(true); getDownloadEngine()->setRefreshInterval(std::chrono::milliseconds(0)); } diff --git a/src/RequestGroup.cc b/src/RequestGroup.cc index cb23c9d7..c8eaa9a1 100644 --- a/src/RequestGroup.cc +++ b/src/RequestGroup.cc @@ -185,24 +185,24 @@ bool RequestGroup::allDownloadFinished() const return pieceStorage_->allDownloadFinished(); } -error_code::Value RequestGroup::downloadResult() const +std::pair RequestGroup::downloadResult() const { if(downloadFinished() && !downloadContext_->isChecksumVerificationNeeded()) { - return error_code::FINISHED; + return std::make_pair(error_code::FINISHED, ""); } if(haltReason_ == RequestGroup::USER_REQUEST) { - return error_code::REMOVED; + return std::make_pair(error_code::REMOVED, ""); } if(lastErrorCode_ == error_code::UNDEFINED) { if(haltReason_ == RequestGroup::SHUTDOWN_SIGNAL) { - return error_code::IN_PROGRESS; + return std::make_pair(error_code::IN_PROGRESS, ""); } - return error_code::UNKNOWN_ERROR; + return std::make_pair(error_code::UNKNOWN_ERROR, ""); } - return lastErrorCode_; + return std::make_pair(lastErrorCode_, lastErrorMessage_); } void RequestGroup::closeFile() @@ -1131,7 +1131,10 @@ std::shared_ptr RequestGroup::createDownloadResult() const res->sessionDownloadLength = st.sessionDownloadLength; res->sessionTime = std::chrono::duration_cast( downloadContext_->calculateSessionTime()); - res->result = downloadResult(); + + auto result = downloadResult(); + res->result = result.first; + res->resultMessage = result.second; res->followedBy = followedByGIDs_; res->belongsTo = belongsToGID_; res->option = option_; diff --git a/src/RequestGroup.h b/src/RequestGroup.h index 44f99768..5b659312 100644 --- a/src/RequestGroup.h +++ b/src/RequestGroup.h @@ -41,6 +41,7 @@ #include #include #include +#include #include "TransferStat.h" #include "TimeA2.h" @@ -163,6 +164,8 @@ private: error_code::Value lastErrorCode_; + std::string lastErrorMessage_; + bool saveControlFile_; bool fileAllocationEnabled_; @@ -195,7 +198,7 @@ private: // download didn't finish and error result is available in // _uriResults, then last result code is returned. Otherwise // returns error_code::UNKNOWN_ERROR. - error_code::Value downloadResult() const; + std::pair downloadResult() const; void removeDefunctControlFile (const std::shared_ptr& progressInfoFile); @@ -478,9 +481,10 @@ public: maxUploadSpeedLimit_ = speed; } - void setLastErrorCode(error_code::Value code) + void setLastErrorCode(error_code::Value code, const char *message = "") { lastErrorCode_ = code; + lastErrorMessage_ = message; } error_code::Value getLastErrorCode() const diff --git a/src/RequestGroupMan.cc b/src/RequestGroupMan.cc index edbccdf8..2333d88b 100644 --- a/src/RequestGroupMan.cc +++ b/src/RequestGroupMan.cc @@ -516,7 +516,7 @@ void RequestGroupMan::fillRequestGroupFromReserver(DownloadEngine* e) } catch(RecoverableException& ex) { A2_LOG_ERROR_EX(EX_EXCEPTION_CAUGHT, ex); A2_LOG_DEBUG("Deleting temporal commands."); - groupToAdd->setLastErrorCode(ex.getErrorCode()); + groupToAdd->setLastErrorCode(ex.getErrorCode(), ex.what()); // We add groupToAdd to e later in order to it is processed in // removeStoppedGroup(). requestQueueCheck(); diff --git a/src/RpcMethodImpl.cc b/src/RpcMethodImpl.cc index f8a043b1..7b1b8fbd 100644 --- a/src/RpcMethodImpl.cc +++ b/src/RpcMethodImpl.cc @@ -96,6 +96,7 @@ const char VLB_ZERO[] = "0"; const char KEY_GID[] = "gid"; const char KEY_ERROR_CODE[] = "errorCode"; +const char KEY_ERROR_MESSAGE[] = "errorMessage"; const char KEY_STATUS[] = "status"; const char KEY_TOTAL_LENGTH[] = "totalLength"; const char KEY_COMPLETED_LENGTH[] = "completedLength"; @@ -812,6 +813,9 @@ void gatherStoppedDownload if(requested_key(keys, KEY_ERROR_CODE)) { entryDict->put(KEY_ERROR_CODE, util::itos(static_cast(ds->result))); } + if(requested_key(keys, KEY_ERROR_MESSAGE)) { + entryDict->put(KEY_ERROR_MESSAGE, ds->resultMessage); + } if(requested_key(keys, KEY_STATUS)) { if(ds->result == error_code::REMOVED) { entryDict->put(KEY_STATUS, VLB_REMOVED);