Exceptions with code and message for QxService
Posted: Tue Aug 14, 2012 1:51 pm
I noticed that there is no ability to send error code and error message from service server code to client. Yes, there is ability to use service method setMessageReturn. But what if i want to send message_return not from service class? I decided to do it using boost::exception. This is my patch:
Using this patch i can send error code and error message like this:
Return xml will look like this:
I can throw this QxException anywhere in project and client will see this message and error code.
What does value mean in message_return parameter?
- Code: Select all
Index: include/QxOrm.h
===================================================================
--- include/QxOrm.h (revision 282)
+++ include/QxOrm.h (revision 283)
@@ -49,6 +49,8 @@
#include <QxPrecompiled.h>
+#include <QxException.h>
+
#include <QxCommon/QxConfig.h>
#include <QxCommon/QxMacro.h>
#include <QxCommon/QxHashValue.h>
Index: include/QxException.h
===================================================================
--- include/QxException.h (revision 0)
+++ include/QxException.h (revision 283)
@@ -0,0 +1,11 @@
+#ifndef QXEXCEPTION_H
+#define QXEXCEPTION_H
+
+#include <boost/exception/all.hpp>
+#include <iostream>
+
+typedef boost::error_info<struct qx_exception_tag_code,int> QxExceptionCode;
+typedef boost::error_info<struct qx_exception_tag_message,std::string> QxExceptionMessage;
+struct QxException: virtual boost::exception, virtual std::exception { };
+
+#endif // QXEXCEPTION_H
Property changes on: include\QxException.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Index: QxOrm.pro
===================================================================
--- QxOrm.pro (revision 282)
+++ QxOrm.pro (revision 283)
@@ -68,6 +68,8 @@
HEADERS += ./include/QxPrecompiled.h
+HEADERS += ./include/QxException.h
+
HEADERS += ./include/QxMemLeak/bool_array.h
HEADERS += ./include/QxMemLeak/class_level_lock.h
HEADERS += ./include/QxMemLeak/cont_ptr_utils.h
Index: src/QxService/QxTransaction.cpp
===================================================================
--- src/QxService/QxTransaction.cpp (revision 282)
+++ src/QxService/QxTransaction.cpp (revision 283)
@@ -31,6 +31,8 @@
#include <QtNetwork/qhostaddress.h>
+#include <QxException.h>
+
#include <QxService/QxTransaction.h>
#include <QxService/QxConnect.h>
#include <QxService/QxTools.h>
@@ -65,6 +67,16 @@
m_pOutputParameter = m_pServiceInstance->getOutputParameter_BaseClass();
m_bMessageReturn = m_pServiceInstance->getMessageReturn();
}
+ catch (QxException & x ) {
+ qx_bool returnValue;
+ if ( int const * code=boost::get_error_info<QxExceptionCode>(x) ) {
+ returnValue.setCode(*code);
+ }
+ if ( std::string const * message=boost::get_error_info<QxExceptionMessage>(x) ) {
+ returnValue.setDesc(QString::fromUtf8((*message).c_str()));
+ }
+ this->setMessageReturn(returnValue);
+ }
catch (const std::exception & e) { QString msg(e.what()); if (msg.isEmpty()) { msg = "[QxOrm] unexpected error occured executing service method"; }; m_bMessageReturn = qx_bool(0, msg); }
catch (...) { m_bMessageReturn = qx_bool(0, "[QxOrm] unknown error occured executing service method"); }
m_pServiceInstance.reset();
Index: src/QxService/QxThread.cpp
===================================================================
--- src/QxService/QxThread.cpp (revision 282)
+++ src/QxService/QxThread.cpp (revision 283)
@@ -32,6 +32,8 @@
#include <QxService/QxTools.h>
#include <QxService/QxConnect.h>
+#include <QxException.h>
+
#include <QxMemLeak/mem_leak.h>
namespace qx {
@@ -90,6 +92,16 @@
Q_EMIT transactionStarted(m_pTransaction);
try { m_pTransaction->executeServer(); }
+ catch (QxException & x ) {
+ qx_bool returnValue;
+ if ( int const * code=boost::get_error_info<QxExceptionCode>(x) ) {
+ returnValue.setCode(*code);
+ }
+ if ( std::string const * message=boost::get_error_info<QxExceptionMessage>(x) ) {
+ returnValue.setDesc(QString::fromUtf8((*message).c_str()));
+ }
+ m_pTransaction->setMessageReturn(returnValue);
+ }
catch (const std::exception & e) { m_pTransaction->setMessageReturn(qx_bool(0, e.what())); }
catch (...) { m_pTransaction->setMessageReturn(qx_bool(0, "unknown error")); }
if (! m_bIsRunning) { return; }
Using this patch i can send error code and error message like this:
- Code: Select all
bool UserManagerDao::authenticate(const QString username, const QString password, const QString serviceName, const QString serviceMethodName)
{
qx::QxSqlQuery query("WHERE user_system_manager.username = :username AND user_system_manager.passwd = MD5(:password)");
query.bind(":username", username);
query.bind(":password", password);
qx::dao::fetch_by_query_with_all_relation(query, *UserManagerCurrent::getSingleton());
if (UserManagerCurrent::getSingleton()->id() == 0) {
throw QxException() << QxExceptionCode(1) << QxExceptionMessage("There is no such user with this password");
}
if (UserManagerCurrent::getSingleton()->status()->isEnabled() == false) {
throw QxException() << QxExceptionCode(2) << QxExceptionMessage(UserManagerCurrent::getSingleton()->status()->caption().toStdString());
}
return true;
}
Return xml will look like this:
- Code: Select all
<qx.service.QxTransaction class_id="0" tracking_level="1" version="0" object_id="_0">
// ....
<service_name>UserManagerService</service_name>
<service_method>currentUser</service_method>
<message_return class_id="3" tracking_level="0" version="0">
<value>0</value>
<code>2</code>
<desc>This user is blocked</desc>
</message_return>
<input_parameter class_id="4" tracking_level="0" version="1">
<px class_id="6" class_name="UserManagerServiceInput" tracking_level="1" version="0" object_id="_1">
<AbstractServiceInput class_id="7" tracking_level="1" version="0" object_id="_2">
<qx.service.IxParameter class_id="5" tracking_level="1" version="0" object_id="_3"></qx.service.IxParameter>
<user>kna</user>
<passwd>123</passwd>
</AbstractServiceInput>
<id>0</id>
<UserManager class_id="8" tracking_level="0" version="1">
<px class_id="-1"></px>
</UserManager>
</px>
</input_parameter>
<output_parameter>
<px class_id="-1"></px>
</output_parameter>
</qx.service.QxTransaction>
I can throw this QxException anywhere in project and client will see this message and error code.
What does value mean in message_return parameter?