My MSMQ is located on a remote machine.
My code is as follows,
private void OnReceiveCompleted(object sender, ReceiveCompletedEventArgs e)
{
System.Messaging.Message msg = _queue.EndReceive(e.AsyncResult);
FireReceiveEvent(msg.Body); // Here msg.Body throws exception
_queue.BeginReceive();
}
I'm running this as a windows service, not sure if that makes a difference. But msg.Body throws a InvaliOperationException.
Infact most of the msg's properties are throwing exceptions. Any idea?
here is a screen shot
Why don't you try casting source parameter as MessageQueue
private void MessageQueueReceiveCompleted(Object source, ReceiveCompletedEventArgs asyncReceive)
{
try
{
//Get a handle to the Message Queue
MessageQueue messageQueue = (MessageQueue)source;
Message message = messageQueue.EndReceive(asyncReceive.AsyncResult);
if (message != null)
{
ProcessMsmqMessage(message.Body);
}
}
catch (Exception e)
{
Exception err = new Exception(String.Format("Error in QueueListener: {0}. Detail: {1}", queueName, e.Message), e);
OnListeningError(err);
}
finally{
messageQueue.BeginReceive();
}
}
OK. So after much work and reading, and banging my head against the wall, I found what the problem was.
REMOTE queues work very differently than local private queues.
You may ask, why? Well... this is probably a deficiency in MS' API.
Remote queues are very icky. They do not support a lot of feature that are available for regular local queues.
For example, in a remote queue unless it's transactional, you cannot do a BeginPeek. You cannot even check message.Body, because it would throw an error.
But that's not all. You cannot even accidentally subscribe to an event like OnPeekCompleted (even if you don't do a BeginPeek). The entire MessageQueue object goes crazy when you do that.
This silly reason was the reason for my headache.
Related
A "side effect" of using Netty is that you need to handle stuff you never thought about, like sockets closing and connection resets. A recurring theme is having your logs stuffed full of java.lang.IOException: Connection reset by peer.
What I am wondering about is how to handle these "correctly" from a web server perspective. AFAIK, this error simply means the other side has closed its socket (for instance, if reloading the web page or similar) while a request was sent to the server.
This is how we currently handle exceptions happening in our pipeline (I think it does not make full sense):
s, not the handler I have attached to the end of the pipeline.
current setup
pipeline.addLast(
new HttpServerCodec(),
new HttpObjectAggregator(MAX_CONTENT_LENGTH),
new HttpChunkContentCompressor(),
new ChunkedWriteHandler()
// lots of handlers
// ...
new InterruptingExceptionHandler()
);
pipeline.addFirst(new OutboundExceptionRouter());
the handler of exceptions
private class InterruptingExceptionHandler extends ChannelInboundHandlerAdapter {
#Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
final var id = ctx.channel().id();
// This needs to ge before the next section as the interrupt handler might shutdown the server before
// we are able to notify the client of the error
ctx.writeAndFlush(serverErrorJSON("A server error happened. Examine the logs for channel id " + id));
if (cause instanceof Error) {
logger.error(format("Error caught at end of pipeline in channel %s, interrupting!", id), cause);
ApplicationPipelineInitializer.this.serverInterruptHook.run();
} else {
logger.error(format("Uncaught user land exception in channel %s for request %s: ", id, requestId(ctx)), cause);
}
}
If some exception, like the IOException, is thrown we try and write a response back. In the case of a closed socket, this will then fail, right? So I guess we should try and detect "connection reset by peer" somehow and just ignore the exception silently to avoid triggering a new issue by writing to a closed socket ... If so, how? Should I try and do err instanceof IOException and err.message.equals("Connection reset by peer") or are there more elegant solutions? To me, it seems like this should be handled by some handler further down in the stack, closer to the HTTP handler
If you wonder about the OutboundExceptionRouter:
/**
* This is the first outbound handler invoked in the pipeline. What it does is add a listener to the
* outbound write promise which will execute future.channel().pipeline().fireExceptionCaught(future.cause())
* when the promise fails.
* The fireExceptionCaught method propagates the exception through the pipeline in the INBOUND direction,
* eventually reaching the ExceptionHandler.
*/
private class OutboundExceptionRouter extends ChannelOutboundHandlerAdapter {
#Override
public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {
promise.addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE);
super.write(ctx, msg, promise);
}
}
After searching for days now and reading pretty much everything related to that, I'm finally posting my question here, since I couldn't find a solution for my specific problem.
I want my REST WebServices to return the original Exception, that has been thrown or at least the correct StackTrace. To test this, I'm using JUnit integrationtests and Wildfly 13 as app-server. After researching I found 2 possible solutions.
1.Using Exception Mappers
While this magical thing catches all of my Exceptions and allows me to return a Response, I've noticed that my StackTrace is changed if I use it like in the example. For example, "com.test.TestClass" is turned into "null.thread" or "null.interceptor". It seems like somehow the exception is changed on the way and the paths to the class are lost or censored, but I can't make sense of it.
Also I couldn't find any restrictions for the Response.entity, be it size, datatype or security.
As far as I understand, you can catch the ExceptionMapper Response OR a WebApplicationException, which contains the response. In my case, the response in the WebApplicationException contains all the relevant data except the (correct) StackTrace.
2.Using WebApplicationException
Another Solution would be to simply throw WebApplicationException instead of ECEException and not using a mapper. If I do that and catch it, the Exception is empty though. It doesn't contain any of the data set, it's always 500 - InternalServerError (I guess, Wildfly couldn't handle it then and threw an exception itself).
Or is it not supposed to be catched/thrown like that? Do I need to convert it to JSon or can I expect it to simply work out of the box with my annotations in the WebServiceInterface and the Response MediaType? Does it even make sense to put a full Response within a WebApplicationException? I mean, both contain fields for the ErrorCode, which seems redundand, even though there is a constructor for that approach.
Long story short:
What's the best approach to catch all possible exceptions and retrieve the full stack trace? Reading this post, I guess catching all "Exception"s is fine and they are always returned as WebApplicationExceptions, but the stack trace is still gone/malformed... your thoughts?
**JUnitTest**
#Test
public void testCreateTask_ClusterInvalid() throws IOException {
final RPETask taskToCreate = new RPETask();;
try
{
final long tid = taskManagerWebService.createTask(taskToCreate);
}
catch (WebApplicationException e) //Responses are ALWAYS catched as WebApplicationException
{
Response response = e.getResponse();
String emString = response.readEntity(String.class);
Gson gson = new Gson();
ECEWebErrorMessage errorMessage = gson.fromJson(emString, ECEWebErrorMessage.class);
errorMessage.displayErrorInformationOnConsole();
}
}
**WebServiceInterface**
#POST
#Path(URI_CREATE_TASK)
#Consumes(WebServiceNames.JSON)
#Produces(WebServiceNames.JSON)
long createTask(final RPETask task) throws ECEException;
**WebService**
#Override
public long createTask(final RPETask task) throws ECEException {
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("createTask(" + task + ")");
}
return taskManager.createTask(task);
}
**ManagerBeanInterface**
long createTask(RPETask task) throws ECEException;
**ManagerBean**
#Override
public long createTask(final RPETask task) throws ECEException {
final ClusterEngineBean cluster = find(ClusterEngineBean.class, task.getCluster());
if (cluster == null) {
throw new ECEObjectNotFoundException(ClusterEngineBean.class, task.getCluster());
}
}
**ExceptionMapper**
#Provider
public class GenericWebExceptionMapper implements ExceptionMapper<Exception> {
final Log logger = LogFactory.getLog(getClass());
#Override
public Response toResponse(Exception ex) {
//At this point, the Exception is fully available -> Sending it as Response breaks it!
logger.error("GenericWebExceptionMapper -> toResponse(Throwable ex)", ex);
ECEWebErrorMessage errorMessage = new ECEWebErrorMessage(500,
ex.getMessage(),
ex.getClass().getCanonicalName(),
ex.getStackTrace());
return Response.status(Status.INTERNAL_SERVER_ERROR)
.entity(errorMessage)
.type(MediaType.APPLICATION_JSON)
.build();
}
}
After more research I've finally found a solution for myself.
Why is the StackTrace gone/malformed?
It's for security reasons. Wildfly automatically detects outgoing StackTraces and censors them, using interceptors. Im not sure if you can do anything about that, but I guess you shouldn't do that anyway.
What is the best approach?
Using Exception Mappers worked for me. Instead of catching them as WebApplicationException, you can always expect a response with the appropriote error code and handle them that way. For example error code 200 = OK, do this... error code 404 = NOTFOUND, do that...I that case your WebServices should always return Responses and contain the object you want to retreive in the entity field of the Response.
Feel free to add additional information to this solution.
I have a project on WinForms with this code:
AppDomain.CurrentDomain.UnhandledException += CurrentDomainUnhandledException;
private void CurrentDomainUnhandledException(object sender, UnhandledExceptionEventArgs e)
{ }
The e.ExceptionObject contains full StackTrace.
In Win Store project:
this.UnhandledException += (s, e) =>{
{
MarkedUp.AnalyticClient.LogLastChanceException(e);
};
e.Exception.StackTrace is null.
Both exceptions were generated by this code:
int a=0;
....
try
{
int i = 1 / a;
}
catch (Exception exp)
{
throw;
}
Any Ideas?
The reference on MSDN suggests that this is a limitation: http://msdn.microsoft.com/en-us/library/windows/apps/windows.ui.xaml.application.unhandledexception
A notable limitation is that the UnhandledException event arguments don’t contain as much detail as the original exception as propagated from app code. Whenever possible, if the app requires specific processing of a certain exception, it’s always better to catch the exception as it propagates, because more detail will be available then. The UnhandledException event arguments expose an exception object through the Exception property. However, the type, message, and stack trace of this exception object are not guaranteed to match those of the original exception that was raised. The event arguments do expose a Message property. In most cases, this will contain the message of the originally raised exception.
Are you running the solution in Debug mode? There seems to be happening something in the App.g.i.cs file when you run the solution in Debug mode. When I run your sample in Release mode the stacktrace is available in the UnhandledException event.
In my test solution it breaks first here:
#if DEBUG && !DISABLE_XAML_GENERATED_BREAK_ON_UNHANDLED_EXCEPTION
UnhandledException += (sender, e) =>
{
if (global::System.Diagnostics.Debugger.IsAttached) global::System.Diagnostics.Debugger.Break();
};
#endif
And after that one it goes to the UnhandledException handler that I have defined in the app.xaml.cs file. In Debug the stacktrace is gone, in Release mode the stacktrace and the exception details are there.
I have a method that creates some Tasks, and then waits on them with WaitAll before returning. The problem is, if those tasks got canceled, then WaitAll throws an AggregateException containing lots of TaskCanceledExceptions.
That means that WaitAll will throw exceptions in two different circumstances:
Exceptions that indicate a genuine error. These mean that there was a condition we didn't know how to handle; they need to propagate as unhandled exceptions, until they eventually terminate the process.
Exceptions that indicate that the user clicked a Cancel button. These mean that the task was canceled and cleaned up, and the program should continue running normally.
The latter fits squarely into the definition of a vexing exception: it's an exception thrown in a completely non-exceptional circumstance, so I have to catch it in order to resume normal control flow. Fortunately it's easy to catch, right? Just add catch (AggregateException) and -- oh wait, that's the same type that gets thrown when there's a fatal error.
I do need to wait for the tasks to finish running before I return (I need to know that they're no longer using their database connections, file handles, or anything else), so I do need the WaitAll or something similar. And if any of the tasks faulted, I do want those exceptions to propagate as unhandled exceptions. I just don't want exceptions for cancel.
How can I prevent WaitAll from throwing exceptions for canceled tasks?
The AggregateException provides a Handle method that can be used for these situations. If for example you want to ignore TaskCanceledException you can do:
var all = new AggregateException(
new NullReferenceException(),
new TaskCanceledException(),
new TaskCanceledException(),
new InvalidOperationException(),
new TaskCanceledException());
try
{
throw all;
}
catch (AggregateException errors)
{
errors.Handle(e => e is TaskCanceledException);
}
If all the exceptions are of type TaskCanceledException, the Handle method will not throw any exception; otherwise a new AggregateException containing only the unhandled exceptions will be thrown.
Based on João Angelo's suggestion, here goes a Task class extension
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace MySharedLibrary.Extensions
{
public static class TaskExtensions
{
// This code is based João Angelo's stackoverflow suggestion https://stackoverflow.com/a/8681687/378115
// Use this when a CancellationTokenSource is used
public static void SafeWait(this Task TargetTask, CancellationTokenSource TargetTaskCancellationTokenSource)
{
if (TargetTaskCancellationTokenSource.IsCancellationRequested == false)
{
TargetTaskCancellationTokenSource.Cancel();
}
SafeWait(TargetTask);
}
// Use this when no CancellationTokenSource is used
public static void SafeWait(this Task TargetTask)
{
try
{
if (TargetTask.IsCanceled == false)
{
TargetTask.Wait();
}
}
catch (AggregateException errors)
{
errors.Handle(e => e is TaskCanceledException);
}
}
}
}
Let's assume we have the following method in the business layer. What's the best practice to tell the UI layer that something went wrong and give also the error message? Should the method return an empty String when it was OK, otherwise the error message, or should it throw another exception in the catch code wrapping the caught exception? If we choose the second variant then the UI should have another try,catch which is too much try,catch maybe. Here is a pseudocode for the first variant.
public String updateSomething()
{
try
{
//Begin transaction here
dataLayer.do1();
dataLayer.do2();
dataLayer.doN();
//Commit transaction code here
}
catch(Exception exc)
{
//Rollback transaction code here
return exc.message;
}
return "";
}
Is this a good practice or should I throw another exception in the catch(then the method will be void)?
I like to return a standard contract to my UI layer from my business layer.
It looks like this:
public class ServiceOperationResult<T>
{
public bool Successful
{
get;
set;
}
public ServiceErrorType ErrorType
{
get;
set;
}
public string ErrorMessage
{
get;
set;
}
public T ReturnData
{
get;
set;
}
}
I use generics so that every service can define what it sends back, and the standard error flags tell the client app what type of error occurred (these are a meta-type, like "Internal error", "External party error", "Business rule validation error") and the app can then react in a standard fashion to these error types.
For instance, business errors are displayed in a red error label, while internal errors get redirected to an error page (in a web app) or close the form (in a windows app)
My pet hate is seeing a red label on a web site (where I expect to see validation errors) and seeing something like "The database server refused your connection" This is the risk that you run by only using a string to return error data.
The best way is wrap exception in some more general type and rethrow it. So updateSomething() must declare that it can throw some sort of Exception (for example: UpdateFailedException) and in catch block you should wrap exception.
public String updateSomething() {
try {
[...]
} catch ( SQLException e ) {
// rollback;
throw new UpdateFailedException(e);
}
}
But catching abstract Exception type is not a good idea. You should wrap only those things which semantic you know. For example: SQLException, DataAccessException (Spring DAO) etc.
If you wrap Exception you easily could wrap InterruptedException of NullPointerException. And this can broke your application.
It's a little unusual to return a String like this (but there's no real reason not too). More usual methods would be:
return a boolean value, and have some method of setting the error message, either by logging it, setting some global "last error" value, or having a pointer to an error construct passed in to your method which you update;
have a void method which throws an exception on failure, and handle it in the calling code (as you suggest)
I have see both of the above used extensively. It's hard to say which is "best". Try to be consistent with the idioms and conventions of the language you are working in and/or the existing code set/libraries you are working with if any.
Probably the best way is to have a custom exception classes specific to layers, once you catch the exception in a particular layer throw the custom exception to the calling layer, having this will have you the following advantage.
you will get the better modular approach to deal with the exception.
the maintenance of the code will be easy when your code complexity increases
you will be having more control on the exception scenarios
for example you catch a exception in the business layer and want to inform Presentation layer
public string DummyFunction
{
try
{
}
catch(Exception ex)
{
throw new businessException();
}
}