I have call mediator with VFS inside to create file. When the saving is failed (no permission) I don't receive timeout error or something else to understand that. That is part from the in sequence:
<property description="Concat path"
expression="fn:concat('vfs:file:///',get-property('BPath'),'/',get-property('dynamic'),'/wso2.file')"
name="Path"
scope="default"
type="STRING"/>
<header expression="get-property('Path')" name="To" scope="default"/>
<property description="OUT_ONLY=true"
name="OUT_ONLY"
scope="default"
type="STRING"
value="true"/>
<call description="">
<endpoint>
<default/>
</endpoint>
</call>
The question is: how to get error message from the call mediator when saving is failed?
Thanks in advance!
Have you tried creating fault sequences or error handlers?
You can add a fault sequence for proxy service:
<faultSequence>
<sequence key="conf:sequences/common/ErrorHandlerSeq.xml"/>
</faultSequence>
Or, to define error handler for the sequence:
<sequence name="mySequence" onError="conf:sequences/common/ErrorHandlerSeq.xml">
...
</sequence>
However, error handling in wso2 is a bit special, your mediator might need to wrap an exception into SynapseException, to get it trigger the error handler.
UPDATE
Following the comment, it looks to be a well-known problem with error handling in WSO2. The culprit is ProxyServiceMessageReceiver.class from synapse-core, having the following lines:
/* */ catch (SynapseException syne)
/* */ {
/* 193 */ if (!synCtx.getFaultStack().isEmpty()) {
/* 194 */ warn(traceOn, "Executing fault handler due to exception encountered", synCtx);
/* 195 */ ((FaultHandler)synCtx.getFaultStack().pop()).handleFault(synCtx, syne);
/* */ }
/* */ else {
/* 198 */ warn(traceOn, "Exception encountered but no fault handler found - message dropped", synCtx);
/* */ }
/* */ }
/* */ finally {
/* 202 */ StatisticsReporter.endReportForAllOnRequestProcessed(synCtx);
/* */ }
The obvious problem here is triggering error handlers only when SynapseException is caught, the others are simply ignored.
If you have a posibility to update classes of your WSO2 instance, you can make it catching all exceptions.
I changed this piece of code with the following:
/* */ catch (Exception syne)
/* */ {
/* 193 */ log.error("Exception caught on mediation sequence", syne);
if (!synCtx.getFaultStack().isEmpty()) {
/* 194 */ warn(traceOn, "Executing fault handler due to exception encountered", synCtx);
try {
/* 195 */ ((FaultHandler)synCtx.getFaultStack().pop()).handleFault(synCtx, syne);
} catch (Exception ex) {
log.error("Exception caught while executing fault handler", ex);
//warn(traceOn, "Exception caught while executing fault handler", synCtx);
if (!synCtx.getFaultStack().isEmpty()) {
warn(traceOn, "Executing nested fault handler", synCtx);
try {
((FaultHandler)synCtx.getFaultStack().pop()).handleFault(synCtx, ex);
} catch (Exception e) {
log.error("Exception caught while executing nested fault handler, mediation stopped", e);
}
} else {
warn(traceOn, "No nested fault handler found - message dropped", synCtx);
}
}
/* */ }
/* */ else {
/* 198 */ warn(traceOn, "Exception encountered but no fault handler found - message dropped", synCtx);
/* */ }
/* */ }
It allows to use even nested error handlers, which is not working out of box, AFAIK.
Related
I am trying to write a long running Subscriber service in Java. I have set up the Listeners to listen to any failures inside the Subscriber service. I am trying to make this fault tolerant and I do not quite understand few things, Below are my doubts/questions.
I have followed the basic setup shown here https://github.com/googleapis/google-cloud-java/blob/master/google-cloud-examples/src/main/java/com/google/cloud/examples/pubsub/snippets/SubscriberSnippets.java. Specifically, I have setup addListener as shown below.
As shown in the following code, initializeSubscriber acts a state variable which will determine if the Subscriber service should restart. Inside the while loop, this variable is continuously monitored to determine if the restart is required.
My question here is,
1. How do I raise an exception inside Subscriber.Listener's failed method and capture it in the main while loop. I tried throwing a new Exception() in failed method and catching it in catch block inside while, However, I am unable to compile the code as it is a checked exception.
2. As shown here, I use Java Executor thread to run the Listener. How do I handle the Listener failures ? Will I able to catch Listener failures under general Exception catch block as shown here ?
try {
boolean initializeSubscriber = true;
while (true) {
try {
if (initializeSubscriber) {
createSingleThreadedSubscriber();
addErrorListenerToSubscriber();
subscriber.startAsync().awaitRunning();
initializeSubscriber = false;
}
// Checks the status of subscriber service every minute
Thread.sleep(60000);
} catch (Exception ex) {
LOGGER.error("Could not start the Subscriber service", ex);
cleanupSubscriber();
initializeSubscriber = true;
}
}
} catch (RuntimeException e) {
} finally {
shutdown();
}
private void addErrorListenerToSubscriber() {
subscriber.addListener(
new Subscriber.Listener() {
#Override
public void failed(Subscriber.State from, Throwable failure) throws RuntimeException {
LOGGER.info("Subscriber reached a failed state due to " + failure.getMessage()
+ ",Restarting Subscriber service");
initializeSubscriber = true;
}
},
Executors.newSingleThreadExecutor());
}
private void cleanupSubscriber() {
try {
if (subscriber != null) {
subscriber.stopAsync().awaitTerminated();
}
if (!subscriptionListener.isShutdown()) {
subscriptionListener.shutdown();
}
} catch (Exception ex) {
LOGGER.error("Error in cleaning up Subscriber thread " + ex);
}
}
It should not be necessary to add a listener to the subscriber if you just want to recreate the subscriber on a failure. You could instead catch the exception on awaitTerminated:
try {
boolean initializeSubscriber = true;
while (initializeSubscriber) {
try {
createSingleThreadedSubscriber();
subscriber.startAsync().awaitRunning();
initializeSubscriber = false;
subscriber.awaitTerminated();
} catch (Exception ex) {
LOGGER.error("Error in the Subscriber service", ex);
cleanupSubscriber();
initializeSubscriber = true;
}
}
} catch (RuntimeException e) {
} finally {
shutdown();
}
If the subscriber shutdown successfully because of a call to stopAsync, then awaitTerminated will not throw an exception. If there was some kind of exception, then awaitTerminated will throw an IllegalStateException because the state will be FAILED instead of TERMINATED.
Note that transient errors are handled by the library itself. For example, if the server become briefly unavailable due to a network hiccup, the library will seamlessly reconnect and continue to deliver messages. Failures that result in a change in state for the subscriber are likely permanent failures such as permission issues (where the account running the subscriber does not have permission to subscribe to the subscription) or resource issues (such as the subscription having been deleted). In these permanent failure cases, recreating the subscriber will likely just result in the same error unless one takes manual steps to intervene and fix the problem.
I've got a block of code that throws an Access Violation when executed. It is the async_connect handler for boost::asio.
//------------------------------------------------------------------------------
void MyClient::OnConnect(const boost::system::error_code & errorCode, boost::asio::ip::tcp::resolver::iterator endpoint)
{
if (errorCode || endpoint == boost::asio::ip::tcp::resolver::iterator())
{
// Error - An error occured while attempting to connect
// Most likely these error codes correspond to https://msdn.microsoft.com/en-us/library/windows/desktop/ms740668(v=vs.85).aspx
std::ostringstream msg;
msg << "An error occured while attempting to connect to " << endpoint->host_name()
<< ". Error code: " << errorCode
<< ". Error Message: " << ErrorCodeToString(errorCode);
LogError(msg.str().c_str(), __FUNCSIG__, __FILE__, __LINE__);
return;
}
// We connected to an endpoint
m_connectionState |= CONNECTED;
In the debugger it looks like the problem is inside endpoint->host_name(), because it tried to get values_[0] while values_ are null.
This is a common Connection Refused scenario. I thought the handler got the endpoint so that it knew who it was trying to connect to! Is there some manner of check I can do on the iterator before I try to call a method on it?
It seems to pass and still throw access violation on
if( endpoint != boost::asio::ip::tcp::resolver::iterator() )
{
std::string blah = endpoint->host_name();
}
Probably you've figured this out by now, but I'll post a few lines in case someone else happens upon it.
This problem looks similar to one I had.
This will not work, and will give similar results to what you're describing.
void establish_connection() {
tcp::resolver resolver(get_asio_io_service()); // this is a problem
tcp::resolver::query q{server_name, "https"};
resolver.async_resolve(q,
[&](asio::error_code ec,
tcp::resolver::iterator it) {
this->handle_resolve(ec, it);
});
}
where establish_connection() is a method in the object that deals with communication to the server.
The resolver object disappears after the establish_connection() exits. You have to find a way to make it stick around. The various demos on the web have it as an attribute of the client object.
Please share your experience with this problem.
I am trying to read a XML file using ticpp::LoadFile(); It was not successfull and I did not know why because I have no idea how to catch the exceptions. Here is what I did:
try
{
// Load a document
ticpp::Document doc( pFilename );
doc.LoadFile();
// Get an element by chaining calls - no return values to check, no TiXmlHandle
ticpp::Element* pElem = doc.FirstChildElement()->NextSibling();
// do something useful here
}
catch( ticpp::Exception& ex )
{
// If any function has an error, execution will enter here.
// Report the error
std::cout << ex.what();
}
But I the ex actually shows grayed as if it is never declared. I am wondering how I can catch the exceptions in this case?
It turned out it was the file path that is messed up.
The code itself is fine.
I already do know, that it is impossible to simply detect if socket is disconnected or not - the server and clients must shout "Can you hear me?" and "Yeah I can." just like we do on skype.
But when boost::asio socket is disconnected from other side I obtain Unhanded exception when trying to read from socket. This is kind of disconnect detection useful enough for me. Can I handle that exception, so instead of crashing, the program will produce message in the console?
Some code for those who need it for everything:
bool SocketClient::read(int bytes, char *text) {
char buffer = 0;
int length = 0;
while(bytes>0) {
size_t len = sock.receive(boost::asio::buffer(&buffer, 1)); //boom: UNHANDLED EXCEPTION
bytes--;
text[length] = buffer;
length++;
}
return true;
}
Because I am connecting to minecraft server, I know when the client is disconnected - exception is caused on any read/write attempt.
try
{
size_t len = sock.receive(boost::asio::buffer(&buffer, 1)); //boom: UNHANDLED EXCEPTION
// More code ...
}
catch (const boost::system::system_error& ex)
{
if ( ex.code() == boost::asio::error::eof )
{
// Work your magic (console logging, retry , bailout etc.)
}
}
Please also take a look at the doc. In the worst case , you could infer the exception type from the debugger :)
i am creating client sever application in windows using socket and i want to throw exception at run time from thread if any problem occur but i am getting error for throw statement.
//create thread in cpp file
CreateThread(NULL,0,startServer,this,0,NULL);
//thread in header file
static unsigned long __stdcall startServer(void *i_SocketTransportServer)
{
((SocketTransportServer*)i_SocketTransportServer)->StartServerThread(((SocketTransportServer *)i_SocketTransportServer)->m_socketServer);
return 0;
}
//and StartServerThread is function called by thread
// SocketTransportServer is inner class of RMLThinTransport
void RMLThinTransport::SocketTransportServer::StartServerThread(SOCKET i_socketServer)
{
m_socketAccept=NULL;
while(true)
{
Sleep(20);
if(m_canAcceptMore)
{
m_canAcceptMore=false;
if(!m_isRunning)
{
break;
}
try
{
m_socketAccept=accept(m_socketServer,NULL,NULL);
if(m_socketAccept==INVALID_SOCKET)
{
int lastError=WSAGetLastError();
closesocket(m_socketAccept);
SocketExceptions
exceptionInAcceptAtServer;
exceptionInAcceptAtServer.detectErrorAccept(&lastError);
throw exceptionInAcceptAtServer;
}
else
{
//_LOG("Client connected",EventTypeInfo) ;
OutputDebugStringW(L"client connected.....");
/* If client connected then setClinetCout value 1 */
setClientCount(1);
m_ClientSockets.push_back(m_socketAccept);
CreateThread(NULL,0,receiveDataAtServer,this,0,NULL);
}
}
catch(SocketExceptions& i_exceptionInAcceptAtServer)
{
/*OutputDebugStringW(L"Can't accept client In Exception. ."); */
throw i_exceptionInAcceptAtServer;//getting runtime error from here
}
}
}
}
now i want to throw error when server close but i am getting run time error. so is there any way so i can get error in my main function.sorry but i am new in c++ so please help me. and error is
The code that throws the exception is not the problem; it's the lack of any code to catch the exception that's the problem. The application is terminating because nothing is catching the exception you're throwing; you must ensure that something is going to catch it. Your startServer method -- the thread procedure -- must catch the exception, and cleanly exit the thread.