none
Catching Global Exceptions in Package

    Question

  • Hi, I am pretty sure this is a newbie question (as I am a newbie at VSExtensibility :D) but didnt found information on the forum yet.

    Is there any way I can catch all the exceptions that happen inside my Package, because currently any exception that I throw kills Visual Studio.

    Thanks in advance,
    Federico

    Friday, March 26, 2010 8:42 PM

Answers

  • Hi Federico,

    There is no way to set up a global handler for all exceptions from a package. In part this is because there's no good answer for the question of "who wins?" if there are multiple such handlers registered.

    Thanks,
    Aaron


    http://blogs.msdn.com/aaronmar
    Monday, March 29, 2010 10:45 PM

All replies

  • Hi Federico,

    Where do you throw the exception? could you please give us an example?

    As I know, we can handle the exception in VSPackage as normal program, don't try...catch fit your requirement?

    Sincerely,
    Wesley


    Please mark the replies as answers if they help and unmark them if they provide no help.
    Welcome to the All-In-One Code Framework! If you have any feedback, please tell us.
    Monday, March 29, 2010 6:10 AM
  • Hi Wesley,

    What I want to do is to be able to handle those unhandled exceptions that do not have a matching try...catch inside my own code. Currently if I throw an exception and I do not catch it.

    The example is the following:

    "I have a bug somewhere that I couldnt replicate, lets say a NullReferenceException get thrown. The exception will bubble up until it hit the package itself. As there are no handlers for that NullReferenceException the exception gets passed to Visual Studio (as I understand)."

    What would I need is to be able to handle those unhandled exceptions so that I can log them, send them to a centralized repository for further inspection.

    Hope that helps,
    Federico

    Monday, March 29, 2010 1:34 PM
  • Hi Federico,

    There is no way to set up a global handler for all exceptions from a package. In part this is because there's no good answer for the question of "who wins?" if there are multiple such handlers registered.

    Thanks,
    Aaron


    http://blogs.msdn.com/aaronmar
    Monday, March 29, 2010 10:45 PM
  • Aaron was right, there is no global exception handler for the whole life of package.  The best way is to debug your package step by step to isolate the issue, and write try...catch block in your code to prevent possible exceptions.

    Sincerely,
    Wesley


    Please mark the replies as answers if they help and unmark them if they provide no help.
    Welcome to the All-In-One Code Framework! If you have any feedback, please tell us.
    Tuesday, March 30, 2010 3:25 AM
  • If you reuse functions in your own code, you can ensure only a few functions can throw exceptions. Then you put try catch wrappers around those functions. For example:

    		public static void ShowPointPopUp(int x, int y)
    		{
    			MenuShowContextMenu(Menus.PointContext, x, y, "ShowPointPopup");
    		}
    
    		static void MenuShowContextMenu(CommandID id, int x, int y, string method)
    		{
    			OleMenuCommandService mcs = MenuCommandService;
    			if (mcs == null)
    				return;
    			try { mcs.ShowContextMenu(id, x, y); }
    			catch (Exception e) { TraceException(e, method); }
    		}
    
    		static void TraceException(Exception e, string function)
    		{
    			Trace.WriteLine(e.Message + "\n" + e.StackTrace.ToString(),
    				"Exception: " + function);
    		}


    check out VG.net: http://www.vgdotnet.com
    Friday, July 02, 2010 3:36 PM
  • In part this is because there's no good answer for the question of "who wins?"

    good point.

     

     

    I agree.

    hmm, if you want to do sth in visual studio,, you mush have a project open;

    can we make 'project' wins?? or projectFactory

      i.e. ask microsoft visual studio team to add a method in ProjectNode, which serve as a global exception handle;

    think about it!

     


    Thanks, B.C.
    Friday, January 28, 2011 12:12 PM
  • >hmm, if you want to do sth in visual studio,, you mush have a project open;

    Not true, I can interact with TFS, look at bugs, open new bugs, open work items, without having a project open.  In general the idea of a 'global' exception handler isn't feasible in VS for more reasons than we can't know 'who wins', reasons such as the massive number of entry points (it isn't like there is one or two places where we call into code that may throw), the fact that VS at its core is a native (C++) application, the fact that it is rather possible to get your code invoked without VS really being involved (i.e. as part of the normal Translate/Dispatch of the main message pump, which is handled by Win32 functions NOT VS explicitly), etc... Catching and ignoring exceptions (which is all VS could do) is very ill advised in terms of stability as you have NO idea what the state of the entire application and all the objects that are inside it are after the exception tore through all their frames.  As an example if an exception is thrown during WPF layout the application gets in a very weird state where the UI behaves very strangely, common things like menus don't work, etc...  WPF 'catches' these exceptions but the damage is already done, lots of internal invariants have been violated, objects are left in states that are 'half updated', etc...

    Ryan

    Friday, January 28, 2011 5:01 PM
  • >hmm, if you want to do sth in visual studio,, you mush have a project open;

    Not true, I can interact with TFS, look at bugs, open new bugs, open work items, without having a project open.  In general the idea of a 'global' exception handler isn't feasible in VS for more reasons than we can't know 'who wins', reasons such as the massive number of entry points (it isn't like there is one or two places where we call into code that may throw), the fact that VS at its core is a native (C++) application, the fact that it is rather possible to get your code invoked without VS really being involved (i.e. as part of the normal Translate/Dispatch of the main message pump, which is handled by Win32 functions NOT VS explicitly), etc... Catching and ignoring exceptions (which is all VS could do) is very ill advised in terms of stability as you have NO idea what the state of the entire application and all the objects that are inside it are after the exception tore through all their frames.  As an example if an exception is thrown during WPF layout the application gets in a very weird state where the UI behaves very strangely, common things like menus don't work, etc...  WPF 'catches' these exceptions but the damage is already done, lots of internal invariants have been violated, objects are left in states that are 'half updated', etc...

    Ryan


    these are very inspiring explanationes.. thanks!

    well, I think there are 2 issues here: 1) should we support global exception handling   2) are we able to support global exception handling

    so, you are saying  1) we shouldn't support global exception handling becaue it's "very ill advised"

                                 2) we are not able to support it, because "it is rather possible to get your code invoked without VS really being involved "

    I partially agree with you for the 1st point;

    however, i think we still are able to support it, if Microsoft visual studio team likes to do it. It's true that our code can be invoked without VS even knowing about it,,

    (like our custom Editor in your example), but remeber that,, visual studio is the *only* process that hold all packages,, and by default our custom editors are all running within the *same* UI thread (unless you create a new UI thread,, which is rarelly used except you want to display some progress bar)

    So, as to the point you talked about "as part of the normal Translate/Dispatch of the main message pump, which is handled by Win32 functions NOT VS explicitly",

    visual studio is that thread that owns that message pump, make sense?

    so we are still able to do it.

     

    I would like to extend this topic, , and see if i can raise a bug/suggestion to microsoft team

     


    Thanks, B.C.
    Saturday, January 29, 2011 8:43 AM
  • Yes, VS runs the thread.  The core of VS is native C++, so to 'protect' the message pump means to do something like

    __try
    {
       //message pump code here
    }
    __catch
    {
       //What do we do here exactly?  
    }

    We know nothing about the state of the application at the point we get our catch handler invoked, in fact if an exception made it all the way back here it is highly likely that lots and lots of frames got 'rudely' terminated. Most people do not write exception safe code (if you think your code is exception safe you may be very wrong) so all of their objects are likely in 'weird' states, VS as a whole may be in a really bad state and if we continue running we will very likely get lots and lots of bug reports like "sometimes I do X and Y and then VS starts acting 'weird'".

    Crashes are actionable, they aren't the best for the end user except they make it highly likely that whatever caused the crash will be investigated, located and fixed. Never crashing doesn't mean your product is stable in any real sense, it means you have ignored all exceptions and your program likely seems to act very, very strangely at seemingly random times.

    You are free to open a bug on Connect, just realize that the area you are talking about is highly complex, there are no easy solutions and a 'global exception handler' is neither an easy nor a good solution. Likely many packages would sign up for such a handler and then how do we decide who to dispatch the exception to? Do we do stack frame analysis to determine who was 'on the stack' when the exception occurred?  The very idea of VS' extensibility is we don't know who is providing the functionality, but to properly dispatch amongst multiple handlers we would have to know that, which eliminates the entire idea of abstraction.  

    The best solution is deal with exceptions in your code where they can arise.  If you want to write some catch-all in your own package you could, but VS as a hosting environment is not in a position to do so very easily and even if it did I think the results would be generally terrible. Any call that goes across a COM boundary (as most calls VS makes into extension points do) automatically has a 'catch all' in the sense that exceptions are turned into HRESULTS which propagate through the normal return value propagation pattern.

    Most applications deal with the exception/stability issue via process level isolation (like IE, FireFox, etc..).  However that is because they are dealing with a small number of extenders/tabs.  I have regularly talked with users who have 20+ extensions installed.  This would mean 20+ child processes + interprocess communication + making all extensibility interfaces COM visible + generating proxies for ALL COM interfaces etc... The perf hit alone would be unacceptable to 99% of our users not to mention the massive amount of work, and while all that work was going on we would be adding 0 other features.  So we would have an entire ship cycle (perhaps more than one) where all we did was institute this isolation.

    In the end writing professional grade software is hard, there is no way around that. To say that VS should handle all of your package's exceptions or that your package should be able to somehow 'catch all' is just a pipe dream in my opinion. You are free to pursue convincing Microsoft that it is a good idea just know that there are people that believe what you are proposing is very ill-advised, and its not because they like crashing software.


    Ryan

    Saturday, January 29, 2011 5:26 PM
  • Hi Ryan,

    thanks for your reply..I read it through, and think they are really great thoughts

    Before this,,I just cannot stop thinking to have such a 'global exception handling' thing, because I have got an experience of being an asp.net developper for a long time and when i was codding asp.net, there is a such kind of thing: Whenever an exception is thrown within a 'page' and was not handled, , it then will be thrown to your 'application' where a predefined virtual "Application_Error" method is there, which you can use to do sth like:

    1) write logs 2) direct user to a custom error page2) give some hints to user in that page on what's going wrong

     

    Then I read your post and begin to think it over,, then I find a similar question: why doesn't winForm support global error handling machnism??

    if winform applications decides not to support it, then for the same reason visual studio would not support it. right?

    (the answer to this question is already explained in your reply)

     

    well, so I think global error hanlding is only applicable to web-based applications (i.e. wet sites),

    for a typical windows application that runs in a local machine, , there is no need to implement it as we don't what to do there;

    Yeah,, i agree with you that it's ill-advised, thanks for your explanation again. ;-)


    Thanks, B.C.
    Sunday, January 30, 2011 2:39 AM
  •   I think it works in non-extensible applications in general.  If you own ALL code inside your application then you are in the best position to determine whether a global exception handling policy will work for you.  With web sites it is slightly different in that it is highly unlikely you have corrupted long lived objects via an exception throw, so logging/redirecting is a viable strategy.  With VS there are objects that live for the life of the application (sometimes weeks), if one of them gets in a wacky state due to getting half-way through some operation and being interrupted by an exception...well who knows WHAT it will do the next time a method on it is called.  Maybe it will work, maybe it will itself throw an exception, maybe it will do random things resulting in further random things :)

    Unfortunately, VS is highly extensible and lots and lots of people extend it, so trying such a 'global' solution runs into lots and lots of problems with no good solutions.  We do take stability seriously and we do try and protect some 'common' failure points, but with the sheer number of extensibility points and the fact that many times your code will be on the callstack with no VS specific bits apart from our core message pump makes dealing with all possible failure modes robustly very difficult.

    Ryan

    Monday, January 31, 2011 7:53 PM