diff --git a/src/XProtocol/XProtocol.hh b/src/XProtocol/XProtocol.hh index c89472b92f9..0524a7f5926 100644 --- a/src/XProtocol/XProtocol.hh +++ b/src/XProtocol/XProtocol.hh @@ -380,6 +380,7 @@ enum XErrorCode { kXR_BadPayload, // 3026 kXR_AttrNotFound, // 3027 kXR_TLSRequired, // 3028 + kXR_noReplicas, // 3029 kXR_ERRFENCE, // Always last valid errcode + 1 kXR_noErrorYet = 10000 }; @@ -1005,31 +1006,32 @@ public: static int mapError(int rc) {if (rc < 0) rc = -rc; switch(rc) - {case ENOENT: return kXR_NotFound; - case EINVAL: return kXR_ArgInvalid; - case EPERM: return kXR_NotAuthorized; - case EACCES: return kXR_NotAuthorized; - case EIO: return kXR_IOError; - case ENOMEM: return kXR_NoMemory; - case ENOBUFS: return kXR_NoMemory; - case ENOSPC: return kXR_NoSpace; - case ENAMETOOLONG: return kXR_ArgTooLong; - case ENETUNREACH: return kXR_noserver; - case ENOTBLK: return kXR_NotFile; - case EISDIR: return kXR_isDirectory; - case EEXIST: return kXR_InvalidRequest; - case ETXTBSY: return kXR_inProgress; - case ENODEV: return kXR_FSError; - case EFAULT: return kXR_ServerError; - case EDOM: return kXR_ChkSumErr; - case EDQUOT: return kXR_overQuota; - case EILSEQ: return kXR_SigVerErr; - case ERANGE: return kXR_DecryptErr; - case EUSERS: return kXR_Overloaded; - case EROFS: return kXR_fsReadOnly; - case ENOATTR: return kXR_AttrNotFound; - case EPROTOTYPE: return kXR_TLSRequired; - default: return kXR_FSError; + {case ENOENT: return kXR_NotFound; + case EINVAL: return kXR_ArgInvalid; + case EPERM: return kXR_NotAuthorized; + case EACCES: return kXR_NotAuthorized; + case EIO: return kXR_IOError; + case ENOMEM: return kXR_NoMemory; + case ENOBUFS: return kXR_NoMemory; + case ENOSPC: return kXR_NoSpace; + case ENAMETOOLONG: return kXR_ArgTooLong; + case ENETUNREACH: return kXR_noserver; + case ENOTBLK: return kXR_NotFile; + case EISDIR: return kXR_isDirectory; + case EEXIST: return kXR_InvalidRequest; + case ETXTBSY: return kXR_inProgress; + case ENODEV: return kXR_FSError; + case EFAULT: return kXR_ServerError; + case EDOM: return kXR_ChkSumErr; + case EDQUOT: return kXR_overQuota; + case EILSEQ: return kXR_SigVerErr; + case ERANGE: return kXR_DecryptErr; + case EUSERS: return kXR_Overloaded; + case EROFS: return kXR_fsReadOnly; + case ENOATTR: return kXR_AttrNotFound; + case EPROTOTYPE: return kXR_TLSRequired; + case EADDRNOTAVAIL: return kXR_noReplicas; + default: return kXR_FSError; } } @@ -1065,6 +1067,7 @@ static int toErrno( int xerr ) case kXR_BadPayload: return EINVAL; case kXR_AttrNotFound: return ENOATTR; case kXR_TLSRequired: return EPROTOTYPE; + case kXR_noReplicas: return EADDRNOTAVAIL; default: return ENOMSG; } } diff --git a/src/XrdCl/XrdClMetalinkRedirector.cc b/src/XrdCl/XrdClMetalinkRedirector.cc index 408e6c45ac0..6116c920c0b 100644 --- a/src/XrdCl/XrdClMetalinkRedirector.cc +++ b/src/XrdCl/XrdClMetalinkRedirector.cc @@ -322,7 +322,7 @@ namespace XrdCl // get the redirect location std::string replica; if( !GetReplica( msg, replica ).IsOK() ) - return GetErrorMsg( msg, "No more replicas to try.", kXR_NotFound ); + return GetErrorMsg( msg, "Metalink: no more replicas to try.", kXR_noReplicas ); Message *resp = new Message( sizeof(ServerResponse) ); ServerResponse* response = reinterpret_cast( resp->GetBuffer() ); diff --git a/src/XrdCl/XrdClXRootDMsgHandler.cc b/src/XrdCl/XrdClXRootDMsgHandler.cc index b4a9b0a2f56..9382c857155 100644 --- a/src/XrdCl/XrdClXRootDMsgHandler.cc +++ b/src/XrdCl/XrdClXRootDMsgHandler.cc @@ -1320,11 +1320,10 @@ namespace XrdCl if( pStatus.code == errErrorResponse ) { st->errNo = rsp->body.error.errnum; - char *errmsg = new char[rsp->hdr.dlen-3]; - errmsg[rsp->hdr.dlen-4] = 0; - memcpy( errmsg, rsp->body.error.errmsg, rsp->hdr.dlen-4 ); + std::string errmsg( rsp->body.error.errmsg, rsp->hdr.dlen-4 ); + if( st->errNo == kXR_noReplicas ) + errmsg += " Last seen error: " + pLastError.ToString(); st->SetErrorMessage( errmsg ); - delete [] errmsg; } else if( pStatus.code == errRedirect ) st->SetErrorMessage( pRedirectUrl ); @@ -2126,7 +2125,10 @@ namespace XrdCl if( status.IsOK() ) return; - pLastError = status; + bool noreplicas = ( status.code == errErrorResponse && + status.errNo == kXR_noReplicas ); + + if( !noreplicas ) pLastError = status; Log *log = DefaultEnv::GetLog(); log->Debug( XRootDMsg, "[%s] Handling error while processing %s: %s.",