I have some Prism work. Specifically, a bootstrapper (MefBootstrapper) that calls InitializeModules. During one of the modules, an exception is raised, when I re-throw this, I get an exception unhandled.
Unsuccessfully, I have added delegate methods to the exception events, like:
AppDomain.CurrentDomain.UnhandledException += CurrentDomainOnUnhandledException;
System.Windows.Application.Current.DispatcherUnhandledException += CurrentOnDispatcherUnhandledException;
First, you need to mark the exception as handled in the event handler attached to AppDomain.CurrentDomain.UnhandledException to keep the application from crashing:
Application.Current.Dispatcher.UnhandledException += (sender, e) => e.Handled = true;
Second, an exception thrown during a given Prism Module initialization can stop other Modules from loading. To circumvent this you can subclass ModuleManager as follows:
public class ErrorHandlingModuleManager : ModuleManager
{
public ErrorHandlingModuleManager(IModuleInitializer moduleInitializer, IModuleCatalog moduleCatalog, ILoggerFacade loggerFacade) : base(moduleInitializer, moduleCatalog, loggerFacade)
{
}
protected override void LoadModulesThatAreReadyForLoad()
{
var initializationExceptions = new List<Exception>();
while (true)
{
try
{
base.LoadModulesThatAreReadyForLoad();
break;
}
catch (ModuleInitializeException e)
{
initializationExceptions.Add(e);
}
catch (Exception e)
{
initializationExceptions.Add(e);
break;
}
}
if (initializationExceptions.Any())
throw new AggregateException(initializationExceptions);
}
}
}
Be sure to register ErrorHandlingModuleManager with your Mef container to override the the default.
Related
When I want just to add more context to any exception that has happened (including parsing errors and even out of memory) I write code as follows
try {
new JsonSlurper().parseText(response)
} catch (any) {
throw new IllegalStateException("Cannot parse response:\n$response", any)
}
This works fine, but I may end up with OutOfMemoryError being wrapped in IllegalStateException which doesn't sound right, as further there could be dedicated exception handling mechanism just for Error throwables.
Is there any way to just add more context to exception and still preserve its original type or category? I.e. when I get OOME, I want to rethrow Error, when I get some parsing exception, I want to rethrow some unchecked exception etc. And of course I don't want to do it manually for each category, as OOME is pretty unlikely and I don't want to produce special code for corner cases (while still I want to be technically correct).
You can definitely do this in groovy by using its metaprogramming features. In particular, for your case metaclasses provides everything you need. Using them you can dynamically add/attach a contextData object to the exception you want it to carry around:
private static void throwsEnhancedException() throws IOException {
try {
throwsBasicException()
} catch (IOException e) {
e.metaClass.contextData = "My context data"
throw e;
}
}
Then to retrieve this contextData in other parts of the code, just inspect the exception object like this:
private static void doSomethingWithContextData(Closure contextDataHandler) throws IOException {
try {
throwsEnhancedException();
} catch (IOException e) {
// RETRIEVE `contextData` FROM `e` OR NULL IF THE PROPERTY DO NOT EXIST
def contextData = e.hasProperty('contextData')?.getProperty(e)
// DO SOMETHING WITH `contextData`
contextDataHandler(contextData)
}
}
There I am using the argument contextDataHandler as a groovy Closure to handle contextData in a flexible manner.
The following is a full working demo of this:
import java.time.LocalDateTime
class ExceptionEnhancer {
static void main(String[] args) {
def logger = { println "${LocalDateTime.now()} - Context Data = [$it]" }
doSomethingWithContextData logger
}
private static void doSomethingWithContextData(Closure contextDataHandler) throws IOException {
try {
throwsEnhancedException();
} catch (IOException e) {
// RETRIEVE `contextData` FROM `e` OR NULL IF THE PROPERTY DO NOT EXIST
def contextData = e.hasProperty('contextData')?.getProperty(e)
// DO SOMETHING WITH `contextData`
contextDataHandler(contextData)
}
}
private static void throwsEnhancedException() throws IOException {
try {
throwsBasicException()
} catch (IOException e) {
e.metaClass.contextData = "My context data"
throw e;
}
}
public static void throwsBasicException() throws IOException {
throw new IOException();
}
}
Complete code on GitHub
Hope this helps.
I have a question , why does java keeps throwing that exception ! Is the problem with the stream ? because I handeled all IOExceptionS !
[[jio0yh.java:12: error: unreported exception IOException; must be
caught or declared to be thrown]]>>
That's the exception that I'm getting!
here is my code
import java.io.*;
public class jio0yh{
public static void main(String[]args){
FileInputStream OD=null;
try{
File f=new File("Binary.dat");
OD= new FileInputStream(f);
byte[]b=new byte[(int)f.length()];
OD.read(b);
for(int i=0;i<b.length;i++)
System.out.println(b[i]);
} catch(FileNotFoundException e){
System.out.println(e.getMessage());
} catch(IOException e){
System.out.println(e.getMessage());
OD.close();
}
}
}
The OD.close(); in your IOException catch block is also susceptible to throwing another IOException.
You should surround the final OD.close() in a finally block:
// ... Any previous try catch code
} finally {
if (OD != null) {
try {
OD.close();
} catch (IOException e) {
// ignore ... any significant errors should already have been
// reported via an IOException from the final flush.
}
}
}
Refer to the following for a more thorough explanation:
Java try/catch/finally best practices while acquiring/closing resources
I'm using the Nhibernate persistence facility from Windor's tutorial:
Kernel.Register(
Component.For<ISessionFactory>()
.UsingFactoryMethod(config.BuildSessionFactory)
.LifeStyle.Singleton,
Component.For<ISession>()
.UsingFactoryMethod(k => k.Resolve<ISessionFactory>().OpenSession())
.LifeStyle.PerWebRequest);
Sometimes my call to config.BuildSessionFactory will fail (maybe my mappings are wrong, or my connection string is invalid or whatever). In the debugger, I can see the Nhibernate exception being thrown. Now Windsor can no longer resolve my ISession either because the factory itself couldn't be instantiated.
The problem is that it doesn't seem to complain about it. Without the debugger, the exception is silently thrown away and the only symptom I have in my app is that all my ISession dependencies are suddenly null. What's the right way to deal with exceptions in UsingFactoryMethod? Is there some way I can tell Windsor to bubble up this exception to my app?
The only why I can see Castle eating the exception is if the session is being injected as a property, which makes Castle consider it optional.
Here's how I fixed it... I created an activator that throws an exception when it fails to set a property's value:
public class StrictComponentActivator : DefaultComponentActivator
{
public StrictComponentActivator(ComponentModel model, IKernelInternal kernel,
ComponentInstanceDelegate onCreation,
ComponentInstanceDelegate onDestruction)
: base(model, kernel, onCreation, onDestruction) { }
protected override void SetUpProperties(object instance, CreationContext context)
{
instance = ProxyUtil.GetUnproxiedInstance(instance);
var resolver = Kernel.Resolver;
foreach(var property in Model.Properties)
{
var value = ObtainPropertyValue(context, property, resolver);
if(value != null)
{
var setMethod = property.Property.GetSetMethod();
try
{
setMethod.Invoke(instance, new[] { value });
}
catch(Exception ex)
{
throw new ComponentActivatorException(
string.Format(
"Error setting property {1}.{0} " +
"in component {2}. " +
"See inner exception for more information. " +
"If you don't want Windsor to set this property " +
"you can do it by either decorating it with " +
"DoNotWireAttribute or via registration API.",
property.Property.Name,
instance.GetType().Name,
Model.Name),
ex, Model);
}
}
}
}
private object ObtainPropertyValue(CreationContext context, PropertySet property, IDependencyResolver resolver)
{
if(property.Dependency.IsOptional == false ||
resolver.CanResolve(context, context.Handler, Model, property.Dependency))
{
try
{
return resolver.Resolve(context, context.Handler, Model, property.Dependency);
}
catch(Exception e)
{
if(property.Dependency.IsOptional == false)
{
throw;
}
Kernel.Logger.Warn(
string.Format("Exception when resolving optional dependency {0} on component {1}.",
property.Dependency, Model.Name), e);
}
}
return null;
}
}
And then I configured most of my components with .Activator<StrictComponentActivator>()
I have some methods which throws some exception, and I want to use AspectJ around advise to calculate the execution time and if some exception is thrown and to log into error log and continue the flow by re-throwing the exception.
I tried to achieve this by following but eclipse says "Unhandled Exception type".
Code-against whom AspectJ is to used :-
public interface Iface {
public void reload() throws TException;
public TUser getUserFromUserId(int userId, String serverId) throws ResumeNotFoundException, TException;
public TUser getUserFromUsername(String username, String serverId) throws ResumeNotFoundException, TException;
public TResume getPartialActiveProfileFromUserId(int userId, int sectionsBitField, String serverId) throws ResumeNotFoundException, UserNotFoundException;
public TResume getPartialActiveProfileFromUsername(String username, int sectionsBitField, String serverId) throws ResumeNotFoundException, UserNotFoundException, TException;
}
Code AspectJ :-
public aspect AspectServerLog {
public static final Logger ERR_LOG = LoggerFactory.getLogger("error");
Object around() : call (* com.abc.Iface.* (..)) {
Object ret;
Throwable ex = null;
StopWatch watch = new Slf4JStopWatch();
try {
ret = proceed();
} catch (UserNotFoundException e) {
ex = e;
throw e;
} catch (ResumeNotFoundException e) {
ex = e;
throw e;
} catch (Throwable e) {
ex = e;
throw new RuntimeException(e);
} finally {
watch.stop(thisJoinPoint.toShortString());
if (ex != null) {
StringBuilder mesg = new StringBuilder("Exception in ");
mesg.append(thisJoinPoint.toShortString()).append('(');
for (Object o : thisJoinPoint.getArgs()) {
mesg.append(o).append(',');
}
mesg.append(')');
ERR_LOG.error(mesg.toString(), ex);
numEx++;
}
}
return ret;
}
}
Please help why this AspectJ is not working.
you can avoid catching the exceptions and just use a try/finally block without the catch.
And if you really need to log the exception you can use an after throwing advice, like this:
public aspect AspectServerLog {
public static final Logger ERR_LOG = LoggerFactory.getLogger("error");
Object around() : call (* com.abc.Iface.* (..)) {
StopWatch watch = new Slf4JStopWatch();
try {
return proceed();
} finally {
watch.stop(thisJoinPoint.toShortString());
}
}
after() throwing (Exception ex) : call (* com.abc.Iface.* (..)) {
StringBuilder mesg = new StringBuilder("Exception in ");
mesg.append(thisJoinPoint.toShortString()).append('(');
for (Object o : thisJoinPoint.getArgs()) {
mesg.append(o).append(',');
}
mesg.append(')');
ERR_LOG.error(mesg.toString(), ex);
}
}
I'm afraid you cannot write advice to throw exceptions that aren't declared to be thrown at the matched join point. Per: http://www.eclipse.org/aspectj/doc/released/progguide/semantics-advice.html :
"An advice declaration must include a throws clause listing the checked exceptions the body may throw. This list of checked exceptions must be compatible with each target join point of the advice, or an error is signalled by the compiler."
There has been discussion on the aspectj mailing list about improving this situation - see threads like this: http://dev.eclipse.org/mhonarc/lists/aspectj-dev/msg01412.html
but basically what you will need to do is different advice for each variant of exception declaration. For example:
Object around() throws ResumeServiceException, ResumeNotFoundException, TException:
call (* Iface.* (..) throws ResumeServiceException, ResumeNotFoundException, TException) {
that will advise everywhere that has those 3 exceptions.
There is an "ugly" workaround - I found them in Spring4 AbstractTransactionAspect
Object around(...): ... {
try {
return proceed(...);
}
catch (RuntimeException ex) {
throw ex;
}
catch (Error err) {
throw err;
}
catch (Throwable thr) {
Rethrower.rethrow(thr);
throw new IllegalStateException("Should never get here", thr);
}
}
/**
* Ugly but safe workaround: We need to be able to propagate checked exceptions,
* despite AspectJ around advice supporting specifically declared exceptions only.
*/
private static class Rethrower {
public static void rethrow(final Throwable exception) {
class CheckedExceptionRethrower<T extends Throwable> {
#SuppressWarnings("unchecked")
private void rethrow(Throwable exception) throws T {
throw (T) exception;
}
}
new CheckedExceptionRethrower<RuntimeException>().rethrow(exception);
}
}
Is there any language that supports something like the below construct, or is there a good way to achieve this using the ubiquitous try-catch-finally?
try
{
} catch(Exception1 e)
{ .... }
catch(Exception2 e)
{ .... }
catch-finally
{
//Perform action, such as logging
}
finally
{
//This always occurs but I only want to log when an exception occurs.
}
I understand this depends on the particular language, but is there some such support in Java, C#, C++, PHP etc?
Put a "global" try/catch in your main program or high-level method. This catches all exceptions that are not caught elsewhere.
try
{
// Main method, or higher level method call
}
catch (Exception ex)
{
// Log exception here
}
Then, in your subordinate try/catch clauses, just handle your exceptions in the usual way, and then rethrow. The rethrown exception will bubble up to your main try/catch and be logged.
try
{
// Do your thing
}
catch(SomeException ex)
{
// Handle exception here
// rethrow exception to logging handler
throw;
}
I don't think so as the behaviour you describe can be easily modelled as:
boolean success = false;
try {
...
success = true;
} catch (Exception_1 e) {
...
}
...
} catch (Exception_N e) {
...
} finally {
if (success) {
// your "finally"
} else {
// your "catch-finally"
}
}
You can easily accomplish that in C#. A simple way would be to save the exception in your catch blocks, then in your finally block, log if the exception object is not null.
Exception ex;
try
{
}
catch (ExceptionType1 type1)
{
ex = type1;
}
catch (ExceptionType2 type2)
{
ex = type2;
}
finally
{
if (ex != null)
{
//Log
}
}
Visual Basic has a construct that can be used for this. This isn't really "finally" in the sense of [almost] never failing to execute, but it'll support the case when you only want to log the exceptions that you're handling, and you have access to the exception object within the shared code. You've also got the flexibility of having the shared code execute before or after the individual exception type code.
Try
...
Catch ex As Exception When TypeOf(ex) Is Type1 OrElse TypeOf(ex) Is Type2
...
If TypeOf(ex) Is Type1 Then
...
ElseIf TypeOf(ex) Is Type2 Then
...
End If
End Try
Something like this, as long as the language has throw with no parameters to rethrow a caught exception:
try
{
} catch(Everything) {
try {
throw;
} catch (Exception1 e) {
....
} catch (Exception2 e) {
....
} finally {
//Perform action, such as logging
}
} finally {
//This always occurs but I only want to log when an exception occurs.
}
That's if you want to log whenever an exception occurs - if you only want to log the ones you actually catch, then don't put the "Perform action" in a finally block, just put it after the end of the inner try-catch.