Sleuth/zipkin with ControllerAdvice is not working - spring-cloud-sleuth

I found there is an old issue Sleuth/Zipkin tracing with #ControllerAdvice, but I meet the same problem with the latest version(spring-cloud-starter-zipkin:2.1.0.RELEASE), I debug it and find that the error is null, so zipkin just guess with statuscode. I have to throw the exception again to make zipkin notify the exception
error is null
zipkin result
ControllerAdvice
throw the exception again, it works

It makes perfect sense that it's null. That's because YOU control the way what happens with the caught exception. In your case, nothing, cause you swallow that exception.
If you want to do sth better, just add the error tag manually via the SpanCustomizer. That way you'll add the exception to the given span. It will then automatically get closed and reported to Zipkin (you can do sth else than ex.toString() of course.
#Slf4j
#RestControllerAdvice
#Order(Ordered.HIGHEST_PRECEDENCE)
public class ExceptionHanders {
private final SpanCustomizer customizer;
public ExceptionHanders(SpanCustomizer customizer) {
this.customizer = customizer;
}
#ExceptionHandler({RuntimeException.class})
#ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
public String handleRuntimeException(Exception ex) throws Exception {
this.customizer.tag("error", ex.toString());
return "testabcd";
}
}

Related

Apache Velocity.init() is throwing an exception

I am using Apache Velocity to create html pages but I am getting an exception while initializing.
Properties p = new Properties();
String path = EmpowERPlugin.getPluginDir()+IEIFileConstants.VELOCITY_PATH;
p.setProperty("resource.loader","file");
p.setProperty("file.resource.loader.path", path);
//p.setProperty ("runtime.log.logsystem.class","org.apache.velocity.runtime.log.NullLogSystem");
p.setProperty("class.resource.loader.class", "org.apache.velocity.runtime.resource.loader.FileResourceLoader");
try{
Velocity.init(p);
}catch(VelocityException e){
e.printStackTrace();
}catch(Exception e1){
e1.printStackTrace()
}finally{
//some code
}
while executing Velocity.init() the control directly goes to the finally block instead of catch, so I am not able to guess what type of exception it is
Exception class isn't catching all possible exceptions although its tricky name:
The class Exception and any subclasses that are not also subclasses of RuntimeException are checked exceptions.
I suggest in your case to catch the superclass Throwable:
The Throwable class is the superclass of all errors and exceptions in the Java language.

Camel Dead Letter Channel for all exceptions

Im creating a dead letter channel errorhandler like below
errorHandler(deadLetterChannel("direct:myDLC").useOriginalMessage().maximumRedeliveries(1));
from("direct:myDLC")
.bean(MyErrorProcessor.class);
The Bean MyErrorProcessor should be able to handle all types of checked and unchecked exceptions like below..
public void process(Exchange exchange) throws Exception {
Exception e=(Exception)exchange.getProperty(Exchange.EXCEPTION_CAUGHT, Exception.class);
e.printStackTrace();
if(e instanceof MyUncheckedException){
logger.error("MyUncheckedException: "+((MyException) e).getErrorCode()+" : "+((MyException) e).getErrorDesc());
}else if(e instanceof MyException){
logger.error("MyException: "+((MyException) e).getErrorCode()+" : "+((MyException) e).getErrorDesc());
}
}
But after exception is handled the original message should be redirected to route's endpoint.. how to continue route once exception handled like this??
Using continued() will work, it will ignore the error and continue to process, so then you would probably want to handle the specific Exception
see http://camel.apache.org/exception-clause.html
onException(MyException.class)
.continued(true)
;
If you would use .useOriginalMessage() on this exception handling, the original message would be the message that is continued.

How to catch exception with action composition in Play 2.3.X

I'm developing an application using Play 2.3.1.
I'm annotating all my controllers with the following Action :
#Override
public Promise<Result> call(final Context ctx) throws Throwable {
try {
return delegate.call(ctx);
} catch (MyCustomException e) {
return handleCustomException(e);
} catch (Exception e) {
return handleUnexpectedError(e);
}
}
The aim of this action is to catch any exception thrown by a controller method in order to send a clean message to the user.
MyCustomException is my application specific exception that extends Exception.
The problem is that even if I throw a MyCustomException in the method of my controller, the corresponding catch statement is never executed.
I always have a RuntimeException caused by my MyCustomException.
The consequence is that no matter what exception occured, the user always sees the result sent by handleUnexpectedError(e).
What am I doing wrong ? Thanks.
After some investigation, the guilty is the Security action of Play.
More details here : https://groups.google.com/forum/#!topic/play-framework/AY4NuQziYyM
Because I added my custom actions at AbstractController level and the #Authenticated(Authenticator.class) annotation at the controller level, the security action composition is the last one to be executed.
Because of the Security.java at line 51, even if my exception is expected, Play throws a RuntimeException.
So the solution is to add the security annotation at method level in order to be sure that it is executed before the first execution of the method.

Handling Windows Store App exceptions from GetFileAsync

I have a problem with the following code example:
Windows::Storage::StorageFolder^ location = Package::Current->InstalledLocation;
try
{
task<StorageFile^> GetFileTask(location->GetFileAsync(sn));
GetFileTask.then([=](StorageFile^ file)
{
try
{
task<IBuffer^> ReadFileTask(FileIO::ReadBufferAsync(file));
ReadFileTask.then([=](IBuffer^ readBuffer)
{
// process file contents here
});
}
catch(Platform::Exception^ ex)
{
// Handle error here
}
});
}
catch(Platform::Exception^ ex)
{
// Handle error here
}
When using a filename that doesn't exist the function throws an exception:
Unhandled exception at 0x0FFCC531 (msvcr110d.dll) in GameTest2.exe: An invalid parameter was passed to a function that considers invalid parameters fatal.
I've been searching the internet and this exception breaks only when connected to the debugger. I'm using VS 2012. I've turned off all the relevant 'break on exception' but it still causes the debugger to break and non of my handlers are getting a chance to handle the exception.
If the file is missing I would expect the GetFileAsync method to throw a 'File doesn't exist' exception. Not sure why it keeps throwing the 'Invalid parameter' exception.
This is starting to bother me and I just can't find any known solution to this issue. Anyone have any ideas?
I'm going to try and change the method to not use the task<> code. Instead I'll call the GetFileAsync using 'await'. However I believe 'await' will just cause the calling thread to wait until the GetFileAsync has finished, which kind of defeats the point of asynchronous loading.
I'm wondering if this is a common issue with exception handling when using tasks.
Update:
OK, I've now found the solution:
task<StorageFile^>( location->GetFileAsync(sn)).then([](StorageFile^ openedFile)
{
return FileIO::ReadBufferAsync(openedFile);
}).then([](IBuffer^ readBuffer)
{
// Process file
}).then([](task<void> t)
{
try
{
t.get();
}
catch(Platform::Exception^ e)
{
// Handle error
}
});
It seems there needs to be an extra 'then' condition added to the end of the chain to pick up the exception.

WP7: Unable to catch FaultException in asynchronous calls to WCF service

I am currently developing a Windows Phone 7 App that calls a WCF web service which I also control. The service offers an operation that returns the current user's account information when given a user's login name and password:
[ServiceContract]
public interface IWindowsPhoneService
{
[OperationContract]
[FaultContract(typeof(AuthenticationFault))]
WsAccountInfo GetAccountInfo(string iamLogin, string password);
}
Of course, there is always the possibility of an authentication failure and I want to convey that information to the WP7 app. I could simply return null in that case, but I would like to convey the reason why the authentication failed (i.e. login unknown, wrong password, account blocked, ...).
This is my implementation of the above operation (for testing purposes, all it does is throwing an exception):
public WsAccountInfo GetAccountInfo(string iamLogin, string password)
{
AuthenticationFault fault = new AuthenticationFault();
throw new FaultException<AuthenticationFault>(fault);
}
Now, if I call this operation in my WP7 app, like this:
Global.Proxy.GetAccountInfoCompleted += new EventHandler<RemoteService.GetAccountInfoCompletedEventArgs>(Proxy_GetAccountInfoCompleted);
Global.Proxy.GetAccountInfoAsync(txbLogin.Text, txbPassword.Password);
void Proxy_GetAccountInfoCompleted(object sender, RemoteService.GetAccountInfoCompletedEventArgs e)
{
if (e.Error != null)
{
MessageBox.Show(e.Error.Message);
return;
}
}
The debugger breaks in Reference.cs, saying that FaultException'1 was unhandled, here:
public PhoneApp.RemoteService.WsAccountInfo EndGetAccountInfo(System.IAsyncResult result) {
object[] _args = new object[0];
PhoneApp.RemoteService.WsAccountInfo _result = ((PhoneApp.RemoteService.WsAccountInfo)(base.EndInvoke("GetAccountInfo", _args, result)));
return _result;
}
BEGIN UPDATE 1
When pressing F5, the exception bubbles to:
public PhoneApp.RemoteService.WsAccountInfo Result {
get {
base.RaiseExceptionIfNecessary(); // <-- here
return ((PhoneApp.RemoteService.WsAccountInfo)(this.results[0]));
}
}
and then to:
private void Application_UnhandledException(object sender, ApplicationUnhandledExceptionEventArgs e)
{
if (System.Diagnostics.Debugger.IsAttached)
{
// An unhandled exception has occurred; break into the debugger
System.Diagnostics.Debugger.Break();
}
}
After that, the app terminates (with or without the debugger).
END UPDATE 1
Now, I would love to catch the exception in my code, but I am never given the chance, since my Completed handler is never reached.
Based on similar questions on this site, I have already tried the following:
Re-add the service reference --> no change
Re-create a really simple WCF service from scratch --> same problem
Start the app without the debugger to keep the app from breaking into the debugger --> well, it doesn't break, but the exception is not caught either, the app simply exits
Tell VS 2010 not to break on FaultExceptions (Debug > Options) --> does not have any effect
wrap every line in my app in try { ... } catch (FaultException) {} or even catch (Exception) --> never called.
BEGIN UPDATE 2
What I actually would like to achieve is one of the following:
ideally, reach GetAccountInfoCompleted(...) and be able to retrieve the exception via the GetAccountInfoCompletedEventArgs.Error property, or
be able to catch the exception via a try/catch clause
END UPDATE 2
I would be grateful for any advice that would help me resolve this issue.
The framework seems to read your WsAccountInfo.Result property.
This rethrows the exception on client side.
But you should be the first to read this property.
I don't know your AuthenticationFault class, does it have a DataContractAttribute and is it a known type like the example in
http://msdn.microsoft.com/en-us/library/system.servicemodel.faultcontractattribute.aspx ?
I believe I had the same problem. I resolved it by extending the proxy class and calling the private Begin.../End... methods within the Client object rather than using the public auto-generated methods on the Client object.
For more details, please see:
http://cbailiss.wordpress.com/2014/02/09/wcf-on-windows-phone-unable-to-catch-faultexception/