So I've got this exception defined, protected constructors, static constructor methods (so all the exceptions are generated with the same formatting and I don't have to fight in the constructors. Anyway, this is besides the point... (not my issue? let's leave that alone k?)
public class ValidationException : Exception
{
// Constructors
public static ValidationException Create(IEnumerable<string> errors)
{
// yadda, yadda, yadda, build exception message, pass in errors, configure, shabang...
return vex; // vex is the created exception
}
}
Then I have the following code as part of an NHibernate PreInsertEventListener
.
IDictionary<string, IEnumerable<string>> validationErrors;
if (TryValidateObject(obj, out validationErrors)) return;
throw ValidationException.Create(validationErrors);
Then in my implementation i have this:
try
{
Save();
}
catch (ValidationException)
{
UserMessage.CreateMessage("A Validation error has occured. Please contact your system administrator / software support.").Show();
}
The save function basically does all my final manipulation in NHibernate and executes Flush()
on the data session.
So basically as an overview:
Save()
is called.Flush()
is called in NHibernate- NHibernate's pipeline is executed
- My
PreInsertEventListener
event is called. ValidationException.Create(...)
is called which returns aValidationException
. This is then thrown from thePreInsertEventListener
Now here's the real doosey. The expected behaviour is that the catch
block fires, and catches my ValidationException
, prompting my user message dialog to show up.
But what actually happens is that vstudio & my app in debug hang for about 1 minute. 100% unresponsive, window signals ignored, windows ready to kick the process in the butt, then it finally unsticks and tells me an "Unhandled ValidationException was thrown", at the exact line that im throwing my exception. So somehow this isn't getting caught.
When i run this outside of the debugger, the app insta-fails.
Am i missing something? This all should be executed from the same thread, the call stack is pretty danm clear:
> MyApp.Core.dll!MyApp.Core.Validation.ValidationHelper.DoValidateObject(object obj = {MyApp.Data.Entities.Administration.Career}) Line 153 C# MyApp.Data.Entities.dll!MyApp.Data.Entities.Entity.Validate(out System.Collections.Generic.IDictionary> validationErrors = null, bool throwExceptions = true) Line 73 + 0xa bytes C# MyApp.Data.dll!MyApp.Data.NHibernate.EntityValidateListener.OnPreInsert(NHibernate.Event.PreInsertEvent event = {NHibernate.Event.PreInsertEvent}) Line 23 + 0x30 bytes C# NHibernate.dll!NHibernate.Action.EntityInsertAction.PreInsert() Line 151 + 0x42 bytes C# NHibernate.dll!NHibernate.Action.EntityInsertAction.Execute() Line 44 + 0xd bytes C# NHibernate.dll!NHibernate.Engine.ActionQueue.Execute(NHibernate.Action.IExecutable executable = {EntityInsertAction[MyApp.Data.Entities.Administration.Career#24cda829-e829-4228-997f-55ff890d6eec]}) Line 130 + 0x37 bytes C# NHibernate.dll!NHibernate.Engine.ActionQueue.ExecuteActions(System.Collections.IList list = Count = 1) Line 113 + 0x10 bytes C# NHibernate.dll!NHibernate.Engine.ActionQueue.ExecuteActions() Line 146 + 0x13 bytes C# NHibernate.dll!NHibernate.Event.Default.AbstractFlushingEventListener.PerformExecutions(NHibernate.Event.IEventSource session = {NHibernate.Impl.SessionImpl}) Line 240 + 0x3d bytes C# NHibernate.dll!NHibernate.Event.Default.DefaultFlushEventListener.OnFlush(NHibernate.Event.FlushEvent event = {NHibernate.Event.FlushEvent}) Line 19 + 0x1b bytes C# NHibernate.dll!NHibernate.Impl.SessionImpl.Flush() Line 1187 + 0x92 bytes C# MyApp.Data.dll!MyApp.Data.AbstractDataSession.Flush() Line 57 + 0x36 bytes C# MyApp.UIFramework.dll!MyApp.UIFramework.ViewModel.EntitiesViewModel.Save() Line 110 + 0x2c bytes C# ManagerWPF.exe!ManagerWPF.Modules.Careers.ViewModels.CareersViewModel.HandleSave() Line 274 + 0x11 bytes C# ManagerWPF.exe!ManagerWPF.Modules.Careers.ViewModels.CareersViewModel.get_SaveCommand.AnonymousMethod(object x = null) Line 263 + 0xa bytes C# MyApp.UIFramework.dll!MyApp.UIFramework.Commands.DelegateCommand.Execute(object parameter = null) Line 50 + 0x24 bytes C#