From: Joseph M. Newcomer on
One of the undocumented and painful features of the Automation interface to Office is that
it throws exceptions when there is an error. I handled this by the following technique:

WHERE here;
try {
HERE();
SomeAutomationCall(...);
... stuff
HERE();
SomeOtherAutomationCall(...);
...(repeat above pattern several times)...
}
catch(COleException * e) // or some remarkably similar name...
{
ReportOleException(e, here);
...
return FALSE;
}
return TRUE;

where HERE() stored in the variable (which had to be called 'here') _T(__FILE__) and
__LINE__+1, so the ReportOleException could tell me which line failed. This only worked
because I was able to "lump" all my Automation calls into a single "atomic" (from the
viewpoint of error-handling) sequence. But it made debugging hell. It doesn't help that
the VBA documentation for the internal structures of PowerPoint is among the worst
documention Microsoft has ever written. The most polite thing that can be said about it
is "totally incoherent".
joe

On Wed, 23 Jun 2010 11:39:21 -0400, Hector Santos <sant9442(a)nospam.gmail.com> wrote:

>Today Joe, IMV, its a more a matter of documentation. The overhead is
>somewhat less important in this "Bulky Code" world, attempting to
>optimize for size or speed is of less important or negligible in a
>already heavy handed OS load environment. Developing applications in
>a p-code environments are par for the course today.
>
>I think part of the problem for developers is a separation of whats
>critical vs whats natural and/or expected.
>
>Often the complexity (possibly due to lack or complex documentation)
>promotes using a single catch all (more below).
>
>When the components are "better understood" sometimes being explicit
>in exception trapping is useful, other times its not.
>
>Another problem is that constructors do not lend itself for functional
>programming and exceptions are required, if necessary for the class logic.
>
>And of course, as the generation continues, library designers are more
>oops and event programming oriented and thus use less functional
>programming (FP) techniques and sometimes too much oops orientations
>for the simplest of constructs. As you know, in the early days, good
>library designers (by necessity for the better brand) use to provide
>frameworks for different types of OOPS vs FP programming audience - an
>expensive upkeep in the long run - something has to give, and the
>trend is and has been OOPs, FP mentions gets less attention. But then
>again, the irony is that you see the same people going back to FP
>technique or adding it, ALA F#.
>
>A good example is my recent experiences with my real first .NET
>project, wcLEX (Wildcat! Live Exchange). I am using this project to
>(re)learn all the .NET particulars and "How To's" for the more
>expensive product migration move coming.
>
>Not knowing what are all the possible "error" conditions for the .NET
>library, I got into a practice of wrapping try catch around much of
>the code blocks but also working in the Try Catch Finally logic where
>necessary to return negative or positive results. A good last example
>was adding a search logic using the Regular Expression .NET library.
>
>public bool SearchForums(string sPattern)
>{
> try
> {
>
> Regex rgx = new Regex(sPattern, RegexOptions.IgnoreCase);
> foreach (var forum in ForumsList)
> {
> MatchCollection matches = rgx.Matches(forum.Description);
> if (matches.Count > 0)
> {
> /// got something
> }
> }
> return true;
> }
> catch (Exception ex)
> {
> MessageBox.Show("Regular Expression Error: " + ex.Message);
> }
> return false
>}
>
>This turned out to be nice because for illegal sPattern syntax the
>class throws an exception with detail description of the syntax error.
> I am glad it did this and not me and it also became a "help" for the
>the user and not something we have to documentation.
>
>In short, 10-15 years ago, my belief in using exception was a crutch
>for not understanding code but also sometimes you had no choice before
>the OOPs class did not lend itself to controlled FP methods. But I
>thought it promoted bad coding overall.
>
>Today, I believe that exception trapping is a vital necessary design
>especially for environments .NET. There is still the issue of
>programmings not grasp everything, but the throw exceptions are
>"better" or rather design with the intent that developers will use
>them to provide non-critical feedback.
>
>You can get in trouble though when you don't understand the errors.
>This last example is a good illustration where an explicit exception
>catch was used but was a critical abort failure when implemented in a
>different way.
>
>The Windows Live ID SDK has an example implementation where the main
>program.cs has a catch for specific exception handler for
>
> System.IO.FileNotFoundException
>
>like so:
>
>using System;
>using System.Collections.Generic;
>using System.Windows.Forms;
>using Microsoft.Win32;
>
>namespace WindowsLiveIDClientSample
>{
> static class Program
> {
> /// <summary>
> /// The main entry point for the application.
> /// </summary>
> [STAThread]
> static void Main()
> {
> Application.EnableVisualStyles();
> Application.SetCompatibleTextRenderingDefault(false);
>
> try
> {
> Application.Run(new MainWindow());
> }
> //System requirement detection.
> catch (System.IO.FileNotFoundException fnfex)
> {
> //Checking for the absence of the Windows Live
>Sign-In Assistant DLL.
> if (fnfex.Message.Contains("WindowsLive.ID.Client"))
> {
> MessageBox.Show("Please install the Windows Live
>ID For Client Applications SDK.");
> }
> else
> {
> MessageBox.Show(fnfex.Message);
> }
> }
> finally
> {
> Application.Exit();
> }
> }
> }
>}
>
>Well, if you isolate this LiveID class into your own library and the
>LiveID component was not already installed, then you get an exception
>that is not System.IO.FileNotFoundException.
>
>I learn the hard way that this exception was only correct when the
>LiveID assembly was bound to the EXE and not a helper DLL.
>
>The solution was simple, again, not knowing what are the possible
>specific exceptions, I used catch all instead and checked for the
>"LiveID" string in the exception message.
>
>My take on it.
>
>The sad fact is this - its here. It is what it is, libraries are done
>mostly one way now and developers have no choice but get use to it and
>learn how to work with it.
Joseph M. Newcomer [MVP]
email: newcomer(a)flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
From: Joseph M. Newcomer on
Actually, I have not only written hundreds of thousands of lines of C code without a goto
(perhaps, actually, in excess of a million), but have managed to take goto code and remove
the gotos.
joe

On Wed, 23 Jun 2010 00:18:56 -0700 (PDT), Goran <goran.pusic(a)gmail.com> wrote:

>On Jun 23, 1:49�am, Joseph M. Newcomer <newco...(a)flounder.com> wrote:
>> Key here is how much you have to do in the catch. �Putting all the recovery code in the
>> catch would consolidate it and eliminate that horror of "goto exit" that happens so often.
>
>Hey, +1 for this.
>
>goto is for me forbidden in C++ (but arguably the best approach for
>the likes of C).
>
>Goran.
Joseph M. Newcomer [MVP]
email: newcomer(a)flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
From: Hector Santos on
Good Point Giovanni.

Off hand, as you mentioned this, my mind is thinking the Two step
approach was common with Borland Pascal Oops or POOP as I use to call
it. <g>

But I never really understood why a FP approach was not a big
consideration for construction:

SomeClass *sc = new SomeClass();
if (sc == NULL) {
//some constructor error occurred
}

I guess you could do a macro, template or something if you wanted this.

--

Giovanni Dicanio wrote:

> On 23/06/2010 17:39, Hector Santos wrote:
>
>> Another problem is that constructors do not lend itself for functional
>> programming and exceptions are required, if necessary for the class
>> logic.
>
> Note that there is an alternative design: two-step construction.
> (This is widely used in MFC as well, e.g. CWnd default constructor
> basically puts the object in a safe state, but then you need to call
> CWnd::Create/CreateEx).
>
> With two-step construction you don't need to throw exception in ctor,
> because the default ctor just puts the object in a safe state (e.g. zero
> the pointers, etc.) and the actual construction is done in a /ad hoc/
> construction method (e.g. Init(), Create()...).
>
> Note also that if you throw an exception in the ctor, the destructor is
> *not* called! So, to write exception-safe code, you should pay attention
> to this point and provide proper cleanup code in ctor as well.
> This is bad, IMHO.
> But this problem doesn't occure in two-step construction: in fact, the
> default ctor doesn't throw, and if the Init()/Create() construction
> method throws, the destructor is properly called.
>
> Moreover, you can't call (or is it not safe to call...) virtual methods
> in a ctor; but you can call virtual methods in an Init()/Create()
> method, after the default ctor put the object in a safe state.
>
> I like the two-step construction pattern for C++, and I listed above
> some reasons (even if the C++-FAQ discourages its use).
>
>
> Giovanni
>



--
HLS
From: Hector Santos on
Giovanni Dicanio wrote:

> On 23/06/2010 17:39, Hector Santos wrote:
>
>> public bool SearchForums(string sPattern)
>> {
>> try
>> {
>>
>> Regex rgx = new Regex(sPattern, RegexOptions.IgnoreCase);
>> foreach (var forum in ForumsList)
>> {
>> MatchCollection matches = rgx.Matches(forum.Description);
>> if (matches.Count > 0)
>> {
>> /// got something
>> }
>> }
>> return true;
>> }
>> catch (Exception ex)
>> {
>> MessageBox.Show("Regular Expression Error: " + ex.Message);
>> }
>> return false
>> }
>>
>> This turned out to be nice
>
> catching(Exception) in C# is like catch(...) in C++: basically you are
> swallowing everything... but IMHO you should only process Regex related
> exception.
>
> I don't know the details of .NET Regex, but I think they should have
> designed an /ad hoc/ exception class for regex (e.g. RegexError), so
> that you could selectively catch RegexError and not swallow unrelated
> exceptions.
>
> Note also that C# exceptions are better designed than C++ ones.
> For example, you can put localized strings in C# exceptions, it is
> possible to nest C# exceptions (see e.g. Exception.InnerException
> property) to provide better diagnosis, etc.
>
> Giovanni


You see, you made my point, one has to be knowledgable of the error
exceptions and traps for each class in order to consider specific
trappings. :)

But as I also pointed out, I came across where using the specific
trapping MAY only apply to a specific binding or integration.

Yes, when I was diagnosing and debugging the issue I came across with
the Live ID reference assembly from a DLL rather than the example
usage with a direct reference in the EXE example, I studied up on the
exception levels and inner exception stuff.

I figured, atleast for now, I can cover both usages with the Live ID
SDK DLL is bound to an EXE or my helper DLL using the catch all.

I saw it somewhat of a chicken and egg situation for general
applicability. If a DLL is missing, then any specific DLL Exception
class will not be available, hence the critical abort.

I have to go back to verify what happen and what I found under debug,
but I think that is what happen here.

In my helper DLL, I have a InitializeWindowsLive() class method:

private bool InitializeWindowsLive()
{
try
{
oIDMgr = IdentityManager.CreateInstance(AppId, AppName);
return oIDMgr != null;
}
catch (WLLogOnException wlex)
{
ShowError("WLLogOnException: {0}",wlex.message);
}
catch (Exception ex)
{
ShowError("InitializeWindowsLive(): {0}" + ex.Message);
}
return false;
}

When Program.cs had the original usage of the SDK example using the
System.IO.FileNotFoundException catch only, I guess delayed loading
occurred when the LiveID DLL was bound to the EXE. Hence this catch
would work.

But I used a helper DLL and the LiveID DLL was bound to it, the
InitializeWindowsLive() error if I remember was that the
WLogOnException was not found because the DLL was not found.

I don't remember if I had the 2nd catch in the Initialize function or
it was part of the solution, but for sure the program.cs could not use
the System.IO.FileNotFoundException catch. I had tried to use the
InnerException too I recall, overall I was dumping everything to see
what I can "hold on" too to catch the overall error of the separate
LiveID DLL not being installed on user machine.

The point is that even using specific exceptions for the library MAY
NOT work if the library itself is missing.

I MAY or MAY NOT be saying that using a catch all may be necessary
MOST of the time.

--
HLS
From: Joseph M. Newcomer on
See below...
On Wed, 23 Jun 2010 08:34:54 -0700, "David Ching" <dc(a)remove-this.dcsoft.com> wrote:

>"Joseph M. Newcomer" <newcomer(a)flounder.com> wrote in message
>news:398426d1hill1o2bbf1m7ddm5jt4sohumm(a)4ax.com...
>> Well, we were not discussing .NET exceptions, we were discussing C++
>> exceptions. Since I
>> had never heard of either Parse or TryParse, there was no easy way to
>> detect these were
>> something in .NET and not in some part of C++ I had not seen.
>>
>> I have no data on .NET exception handling.
>>
>
>Why does it make a difference if it is .NET or C++? The concept is exactly
>the same.
****
Performance. Throwing an exception in .NET involves a lot more effort because of the need
to manage references. Abstractly, they are identical; for raw performance, .NET requires
more work to handle cleanup (note that the cleanup has to be done anyway, but in the
context of an excption there is apparently additional costs)

The Bliss-11 language had a truly high-performance exception handling mechanism. When
Digital created Bliss-16, they created a vastly more complex (and vastly slower) exception
mechanism that tried to solve too many irrlevant problems (such as allowing "recoverable"
exceptions, which I consider a serious design defect). So even in a low-level language
like Bliss it was possible to get serious performance problems in the exception handling
mechanism, based solely on the implementation. The resulting exception mechanism in
Bliss-16 was so convoluted and baroque that nobody could even figure out how to use it (I
had a lot of trouble, and I actually understood the design!)

So yes, implementation details matter, and in this case, apparently matter a lot.
****
>
>
>> As you point out, if you have a lot of really bad input, why is it really
>> bad input? I
>> would have applied a Parse operation to something vastly more complex than
>> an integer
>> (e.g., an entire script), in which case an exception makes more sense. I
>> had no idea it
>> applied to concepts as trivial as just parsing numbers.
>
>Again, what does it matter if you are parsing ints or scripts? The concept
>is exactly the same.
****
If I am parsing integers, I might need to parse millions of them; if I am parsing scripts,
I might need to process less than 10 of them in a given execution. Scale matters.

Sadlly, it sounds like the mechanism was complete overkill for something as trivial as
parsing a simple number, and probably didn't extend to parsing other interesting syntactic
constructs (e..g, part numbers, social security numbers, etc.), so I question the utility
of something that could not handle millions of integers efficiently. Even if there were
errors.
joe
****
>
>
>-- David
Joseph M. Newcomer [MVP]
email: newcomer(a)flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm