mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-07-11 22:03:01 -06:00
XmlRpc: Improved error handling
git-svn-id: svn://ultimatepp.org/upp/trunk@2207 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
parent
8a606a5145
commit
90b2cec2b8
4 changed files with 93 additions and 26 deletions
|
|
@ -1223,7 +1223,7 @@ bool FileSel::Execute(int _mode) {
|
|||
dir.Add(GetHomeDirectory());
|
||||
#ifdef PLATFORM_POSIX
|
||||
Array<FileSystemInfo::FileInfo> root = filesystem->Find("/media/*");
|
||||
dir.Add(GetHomeDirFile("Desktop"));
|
||||
dir.Add(GetDesktopFolder());
|
||||
dir.Add("/");
|
||||
for(i = 0; i < root.GetCount(); i++) {
|
||||
String ugly = root[i].filename;
|
||||
|
|
|
|||
|
|
@ -2,13 +2,36 @@
|
|||
|
||||
#define LLOG(x) // LOG(x)
|
||||
|
||||
XmlRpcCall::XmlRpcCall(const char *url)
|
||||
XmlRpcCall& XmlRpcCall::URL(const char *url)
|
||||
{
|
||||
shorted = true;
|
||||
if(url && *url) {
|
||||
server.URL(url);
|
||||
shorted = false;
|
||||
}
|
||||
shouldExecute = true;
|
||||
return *this;
|
||||
}
|
||||
|
||||
XmlRpcCall& XmlRpcCall::Method(const char *name)
|
||||
{
|
||||
shouldExecute = true;
|
||||
method = name;
|
||||
data.Reset();
|
||||
error.Clear();
|
||||
return *this;
|
||||
}
|
||||
|
||||
XmlRpcCall::XmlRpcCall(const char *url)
|
||||
{
|
||||
URL(url);
|
||||
server.ContentType("text/xml");
|
||||
timeout = 30000;
|
||||
}
|
||||
|
||||
XmlRpcCall::XmlRpcCall()
|
||||
{
|
||||
URL(NULL);
|
||||
server.ContentType("text/xml");
|
||||
timeout = 30000;
|
||||
}
|
||||
|
|
@ -17,6 +40,9 @@ String XmlRpcExecute(const String& request, const char *group, const char *peera
|
|||
|
||||
Value XmlRpcCall::Execute()
|
||||
{
|
||||
if(!shouldExecute)
|
||||
return Value();
|
||||
shouldExecute = false;
|
||||
String request = XmlHeader();
|
||||
request << XmlTag("methodCall")(XmlTag("methodName")(method) + FormatXmlRpcParams(data.out));
|
||||
String response;
|
||||
|
|
@ -26,8 +52,11 @@ Value XmlRpcCall::Execute()
|
|||
response = server.Post(request).TimeoutMsecs(timeout).ExecuteRedirect();
|
||||
LLOG("response: " << response);
|
||||
if(IsNull(response)) {
|
||||
LLOG("ERROR: " << server.GetError());
|
||||
return ErrorValue("Http request failed: " + server.GetError());
|
||||
faultCode = XMLRPC_CLIENT_HTTP_ERROR;
|
||||
faultString = server.GetError();
|
||||
error = "Http request failed: " + faultString;
|
||||
LLOG(error);
|
||||
return ErrorValue(error);
|
||||
}
|
||||
XmlParser p(response);
|
||||
try {
|
||||
|
|
@ -37,11 +66,12 @@ Value XmlRpcCall::Execute()
|
|||
Value m = ParseXmlRpcValue(p);
|
||||
if(IsValueMap(m)) {
|
||||
ValueMap mm = m;
|
||||
String s;
|
||||
s << "Failed '" << mm["faultString"] << "' (" << mm["faultCode"] << ')';
|
||||
error = s;
|
||||
faultString = mm["faultString"];
|
||||
faultCode = mm["faultCode"];
|
||||
error.Clear();
|
||||
error << "Failed '" << faultString << "' (" << faultCode << ')';
|
||||
LLOG(s);
|
||||
return ErrorValue(s);
|
||||
return ErrorValue(error);
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
|
@ -52,18 +82,19 @@ Value XmlRpcCall::Execute()
|
|||
}
|
||||
catch(XmlError e) {
|
||||
String s;
|
||||
s << "XmlError " << e << ": " << p.GetPtr();
|
||||
LLOG(s);
|
||||
error = s;
|
||||
return ErrorValue(s);
|
||||
faultString = e;
|
||||
faultCode = XMLRPC_CLIENT_XML_ERROR;
|
||||
error.Clear();
|
||||
error << "XML Error: " << faultString;
|
||||
LLOG(error << ": " << p.GetPtr());
|
||||
return ErrorValue(error);
|
||||
}
|
||||
return data.in.GetCount() ? data.in[0] : Null;
|
||||
}
|
||||
|
||||
Value XmlRpcCall::Ret()
|
||||
void XmlRpcCall::ClearError()
|
||||
{
|
||||
Value v;
|
||||
if(*this >> v)
|
||||
return v;
|
||||
return Value();
|
||||
faultCode = 0;
|
||||
faultString.Clear();
|
||||
error.Clear();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,6 +14,19 @@ void Register(const char *name, void (*method)(XmlRpcData&), const char *group)
|
|||
XmlRpcMap(group).Add(name, method);
|
||||
}
|
||||
|
||||
struct XmlRpcError {
|
||||
int code;
|
||||
String text;
|
||||
};
|
||||
|
||||
void ThrowXmlRpcError(int code, const char *s)
|
||||
{
|
||||
XmlRpcError e;
|
||||
e.code = code;
|
||||
e.text = s;
|
||||
throw e;
|
||||
}
|
||||
|
||||
String XmlRpcExecute(const String& request, const char *group, const char *peeraddr)
|
||||
{
|
||||
VectorMap< String, void (*)(XmlRpcData&) >& xmlrpcmap = XmlRpcMap(group);
|
||||
|
|
@ -33,13 +46,13 @@ String XmlRpcExecute(const String& request, const char *group, const char *peera
|
|||
data.in = ParseXmlRpcParams(p);
|
||||
int q = xmlrpcmap.Find(methodname);
|
||||
if(q < 0)
|
||||
return FormatXmlRpcError(4, methodname + " method is unknown");
|
||||
return FormatXmlRpcError(XMLRPC_UNKNOWN_METHOD_ERROR, "\'" + methodname + "\' method is unknown");
|
||||
else {
|
||||
(*xmlrpcmap[q])(data);
|
||||
if(IsValueArray(data.out)) {
|
||||
if(IsError(data.out[0])) {
|
||||
LLOG("ProcessingError");
|
||||
return FormatXmlRpcError(3, methodname + " Processing error: " + GetErrorText(data.out[0]));
|
||||
return FormatXmlRpcError(XMLRPC_SERVER_PROCESSING_ERROR, "Processing error: " + GetErrorText(data.out[0]));
|
||||
}
|
||||
r << FormatXmlRpcParams(data.out);
|
||||
}
|
||||
|
|
@ -48,13 +61,17 @@ String XmlRpcExecute(const String& request, const char *group, const char *peera
|
|||
p.PassEnd();
|
||||
return r;
|
||||
}
|
||||
catch(XmlRpcError e) {
|
||||
LLOG("Client error: " << e.text);
|
||||
return FormatXmlRpcError(e.code, e.text);
|
||||
}
|
||||
catch(XmlError e) {
|
||||
LLOG("XmlError " << e << ": " << p.GetPtr());
|
||||
return FormatXmlRpcError(1, methodname + " XML Error: " + e);
|
||||
return FormatXmlRpcError(XMLRPC_SERVER_XML_ERROR, "XML Error: " + e);
|
||||
}
|
||||
catch(ValueTypeMismatch) {
|
||||
LLOG("ValueTypeMismatch at parameter " << data.ii);
|
||||
return FormatXmlRpcError(2, methodname + " Value type mismatch at parameter " + AsString(data.ii));
|
||||
return FormatXmlRpcError(XMLRPC_SERVER_PARAM_ERROR, "Parameter mismatch at parameter " + AsString(data.ii));
|
||||
}
|
||||
return Null;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,6 +5,16 @@
|
|||
|
||||
using namespace Upp;
|
||||
|
||||
enum {
|
||||
XMLRPC_CLIENT_HTTP_ERROR = -1000000,
|
||||
XMLRPC_CLIENT_XML_ERROR,
|
||||
XMLRPC_CLIENT_RETTYPE_ERROR,
|
||||
XMLRPC_SERVER_PARAM_ERROR,
|
||||
XMLRPC_SERVER_XML_ERROR,
|
||||
XMLRPC_SERVER_PROCESSING_ERROR,
|
||||
XMLRPC_UNKNOWN_METHOD_ERROR,
|
||||
};
|
||||
|
||||
struct ValueTypeMismatch {};
|
||||
|
||||
void ValueCheck(bool b);
|
||||
|
|
@ -123,16 +133,21 @@ void xmlrpc##x(XmlRpcData& rpc); \
|
|||
INITBLOCK { Register(#x, xmlrpc##x, group); } \
|
||||
void xmlrpc##x(XmlRpcData& rpc)
|
||||
|
||||
void ThrowXmlRpcError(int code, const char *s);
|
||||
|
||||
class XmlRpcCall {
|
||||
bool shorted;
|
||||
HttpClient server;
|
||||
XmlRpcData data;
|
||||
String method;
|
||||
String error;
|
||||
String faultString;
|
||||
int faultCode;
|
||||
int timeout;
|
||||
bool shouldExecute;
|
||||
|
||||
public:
|
||||
XmlRpcCall& Method(const char *name) { method = name; data.Reset(); error.Clear(); return *this; }
|
||||
XmlRpcCall& Method(const char *name);
|
||||
|
||||
template <class T>
|
||||
XmlRpcCall& operator<<(const T& x) { data << x; return *this; }
|
||||
|
|
@ -140,10 +155,8 @@ public:
|
|||
Value Execute();
|
||||
|
||||
template <class T>
|
||||
bool operator>>(T& x) { if(IsError(Execute())) return false; try { data >> x; } catch(ValueTypeMismatch) { return false; } return true; }
|
||||
|
||||
Value Ret();
|
||||
|
||||
bool operator>>(T& x) { if(IsError(Execute())) return false;
|
||||
try { data >> x; } catch(ValueTypeMismatch) { return false; } return true; }
|
||||
XmlRpcCall& operator()(const char *method) { Method(method); return *this; }
|
||||
|
||||
#define E__Templ(I) class COMBINE(T, I)
|
||||
|
|
@ -164,10 +177,16 @@ public:
|
|||
#undef E__Param
|
||||
#undef E__Body
|
||||
|
||||
String GetFaultString() const { return faultString; }
|
||||
int GetFaultCode() const { return faultCode; }
|
||||
String GetError() const { return error; }
|
||||
void ClearError();
|
||||
|
||||
XmlRpcCall& TimeOut(int msec) { timeout = msec; }
|
||||
XmlRpcCall& URL(const char *url);
|
||||
|
||||
XmlRpcCall(const char *url);
|
||||
XmlRpcCall();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue