Exception handling and logging.

R

Roger Down

I have a question regarding exception handling and logging.

First let me explain the situation.

I am creating a .NET library with functionality that I am giving to another
team developer. This other developer does not want to be bother with all
sorts of exceptions from me, but only wants "controlled" return
codes/classes. This is because he wants to take action on whatever return
code / class I return. Makes it easier.

He want however me to log all exception to a common logging system.

An example code could look like this:

public ResultCode SomeMethod()
{
ResultCode resultCode = ResultCode.OK;

try
{
// Do something here...
}
catch( Exception e )
{
Log(e.Message);
resultCode = ResultCode.Error;
}

return resultCode;
}

The other developer can now just check the return code from the SomeMethod()
function.

The problem with the above code is that this is not a recommended way of
using the try & catch framework, because I use the general type Exception in
the catch block... and do not rethrow the exception.

Well... since I can't rethrow the exception I need to do something about the
catch block. I could rewrite the catch block to look something like this:

public ResultCode SomeMethod()
{
ResultCode resultCode = ResultCode.OK;

try
{
// Do something here...
}
catch( ExceptionType1 e1 )
{
Log(e1.Message);
resultCode = ResultCode.Error;
}
catch( ExceptionType2 e2 )
{
Log(e2.Message);
resultCode = ResultCode.Error;
}
catch( ExceptionType3 e3 )
{
Log(e3.Message);
resultCode = ResultCode.Error;
}

return resultCode;
}

This means I need to know every exception that can be thrown from methods in
the try block... The easiest way would be to use some type of general
Exception type, that will catch all those exceptions so I don't need to
write all those catch blocks.

But perhaps there are some easier (or other) ways of dealing with this
situation ?


Best of regards...
 
D

David Levine

Roger Down said:
I have a question regarding exception handling and logging.

First let me explain the situation.

I am creating a .NET library with functionality that I am giving to
another team developer. This other developer does not want to be bother
with all sorts of exceptions from me, but only wants "controlled" return
codes/classes. This is because he wants to take action on whatever return
code / class I return. Makes it easier.

This is the essential problem - the other developer wants to deal with .NET
code as if he was writing his app in C. Tell this other developer to deal
with exceptions because he really has no choice. Even if your module does
not throw exceptions, the entire framework does, as do other 3rd party
libraries.
He want however me to log all exception to a common logging system.

You could do that, but then so can the main application. This really ought
to be handled in a global logging mechanism so that application itself can
set a logging policy. How is your module supposed to know where to log the
data to? If it can change, how is it configured? When should it be logged?
How is the user notified a problem occurred?There are many design questions
that ought to be addressed - a single component in the system usually does
not have enough context to make all the decisions.

The other developer can now just check the return code from the
SomeMethod() function.

Again, this is very bad practice with .NET code. It increases the liklihood
that an error condition will be missed or ignored.
 
R

Roger Down

Hi David, and thanks for the answer... :)

My replies are inline...

David said:
This is the essential problem - the other developer wants to deal
with .NET code as if he was writing his app in C. Tell this other
developer to deal with exceptions because he really has no choice.
Even if your module does not throw exceptions, the entire framework
does, as do other 3rd party libraries.

He is dealing with .NET exceptions, but only those that are a part of his
code.

Lets say my code/library contains many types of functionality. Sending all
those (possible) exceptions to the level above me, I think is not good. An
alternative could always be to throw my own exception to the level above me,
but in my eyes that is just another way of returning some result code.
You could do that, but then so can the main application.

Of course, but the details of the exception is in the catch block in my
code. So if I can write the detailed information to a logging system, why
not ? An example is the SqlException that contains a lot of information from
the database / stored procedures. This information is not always interesting
for the level above me. He just want to know if I accomplished what my
method described.
Again, this is very bad practice with .NET code. It increases the
liklihood that an error condition will be missed or ignored.

Hmm... well, I don't think its that bad practice. It's easy to maintain,
easy to read and handles the various error situations.

I guess the reason for not using the exception system more "correctly" is
the different advices written all over. There are so many opinions about the
exception system, so the recommandations (best practices) written by
Microsoft perhaps isn't that clear... I don't know.

I also think that not all exceptions are very well documented by Microsoft,
or it is hard to find. This of course makes it hard to decide if I should
use even more time digging into different parts of the msdn documentation to
find all those exceptions that can occur... or just go with the
"unrecommended" Exception type. I know many people who choose the last
solution. I have been using the remoting framework a bit, and I thinkn some
of those exception can be a bit difficult.



Best of regards...
 
D

David Levine

He is dealing with .NET exceptions, but only those that are a part of his

I'm not quite sure what this means....the exceptions he is dealing with are
being thrown by other modules - why treat yours differently? It would
probably be much easier to deal with if he treated all external modules the
same and used the same error handling mechanisms for all of them.
Lets say my code/library contains many types of functionality. Sending all
those (possible) exceptions to the level above me, I think is not good. An
alternative could always be to throw my own exception to the level above
me, but in my eyes that is just another way of returning some result code.

You are correct that it is a different means of signalling that an error
occurred, and that using different exception types is similar to using
different error codes, but it is the side-effects that are important. Error
codes are simple values - exceptions are objects that are contain complete
information about the error.

You can build a complete message about the error and associate additional
context information with it. If you return a value then the caller must
translate a value into a message, and the translation process itself is
error prone (e.g . which module returned the error? Which lookup table
should it use to translate the code into a string?) The caller must provide
lookup tables to generate an error message, or it may ignore the actual
value and report a generic error and lose the actual cause of the error.

An exception object also contains a stack trace that can be invaluable in
tracking down the cause of an error.

The use of exceptions makes it possible to be notified when an unhandled
exception has occurred; this simply is not an option with error codes.

Systems can be built entirely around error codes, but experience has shown
it requires great discipline throughout the entire implementation. It's not
that it cannot be done (it can and it has),

Of course, but the details of the exception is in the catch block in my
code. So if I can write the detailed information to a logging system, why
not ?

You certainly can, and in a small system this may be the preferred method,
but in a large system of components glued together by the application there
are policy decisions that ought to be defined and implemented by a
centralized policy mechanism, not the component itself. In my opinion,
where, how, and when to log errors is one of these policies. Centralizing
the logging is one aspect of it, knowing when to log is another. This may
not be an issue in your case.

An example is the SqlException that contains a lot of information from the
database / stored procedures. This information is not always interesting
for the level above me. He just want to know if I accomplished what my
method described.

Perhaps, but then again, perhaps not. These design decisions are specific to
the implementation. If you are writing a custom piece of code to his specs,
and these will never change, then it's less of an issue.
Hmm... well, I don't think its that bad practice. It's easy to maintain,
easy to read and handles the various error situations.

It can lead to different mechanisms for dealing with error conditions, and
that by itself tends to be error-prone. I find it more difficult to use two
different mechanisms for dealing with errors.

It could be a problem to mix the two systems together. It can lead to
situations where one component returns an error code, the layer above sees
this and throws an exception, the layer above that catches it and translates
it back into an error code, and so-on. A lot of this depends on the
circumstances. I think it more a problem for large systems where many
developers are working on many different modules. For small systems/projects
this is less of a concern.
I guess the reason for not using the exception system more "correctly" is
the different advices written all over. There are so many opinions about
the exception system, so the recommandations (best practices) written by
Microsoft perhaps isn't that clear... I don't know.

I agree, the "best practices" advice can be conflicting and difficult to
follow, or even wrong.
I also think that not all exceptions are very well documented by
Microsoft, or it is hard to find. This of course makes it hard to decide
if I should use even more time digging into different parts of the msdn
documentation to find all those exceptions that can occur... or just go
with the "unrecommended" Exception type. I know many people who choose the
last solution. I have been using the remoting framework a bit, and I
thinkn some of those exception can be a bit difficult.
I agree - the list of exceptions that can be thrown is not always documented
or complete so I tend to catch the generic Exception type.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top