Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

I don't see much of a difference between the concerns of exception handling and logging in that both are cross cutting concerns. What do you think? Shouldn't it be handled separately on its own rather than interleaved with the core logic a method is implementing?

EDIT: What I am trying to say, is that in my opinion a method implementation should only contain the logic for the successful path of execution and exceptions should be handled elsewhere. This is not about checked/unchecked exceptions.

For example, a language might handle exceptions in a fully checked way by using constructs like this:

class FileReader {

  public String readFile(String path) {
    // implement the reading logic, avoid exception handling
  }

}

handler FileReader {

   handle String readFile(String path) {
      when (IOException joe) {
        // somehow access the FileInputStram and close it
      }
   }

}

In the above conceptual language, the program won't compile in the absence of FileReader handler, because the FileReader class's readFile is not throwing the exception. So by declaring the FileReader handler, the compiler can ensure that it is being handled and the program then compiles.

This way we have the best of both of checked and unchecked exception problems: robustness and readability.

share|improve this question
add comment

4 Answers

up vote 11 down vote accepted

In some cases yes

In the cases where you have an exception that you want logged (which I would assume to be almost always) then yes the exception is tied to a cross cutting concern.

Most of the time no

However take the instance of a SocketListener, if a socketlistener throws an exception due to the other end dropping the connection, then this should be anticipated behavior and so the application should act according to the circumstances which caused the exception. This is not something that a generic Aspect should handle, and so should not be a cross cutting concern.

Identifying a cross cutting concern

If you are duplicating the same code over and over again it needs to be abstracted. If the abstraction promotes itself to multiple layers, it could be a cross cutting concern. Only then should it be considered.

share|improve this answer
add comment

Logging is optional. Handling exceptions isn't.

Logging is pretty generic and while it sources from specific logic it feeds to a generic consumer. Exceptions are always specific to the logic and some code knowledgeable about that logic has to handle the mess it made.

At least in my limited use of the two that means that the two goals are best handled in different ways and not under the same design umbrella.

share|improve this answer
add comment

I view exception handling as a cross-cutting concern for certain types of exceptions. There are local exceptions that only the immediate calling code can handle correctly. An example might be a database exception when trying to execute a query. But there are also exceptions that can and should be handled more globally. An example might be an exception related to lack of security credentials (force the user to log in again). Or at the very least you need a global handler in case an exception slips through the more specific code, to explain to the user what they should do to restart or send a log to IT or something like that. For these types of globally handled exceptions, it is a cross-cutting concern.

share|improve this answer
add comment

I think this ties in with the issue of leaky abstractions.

Many exceptions should be caught and rethrown as they propogate through the layers of abstraction. The re-throwing should throw the exception in a new form, appropriate to the abstraction that is doing the re-throwing, so that it makes sense as part of the interface. In other words, exceptions from lower levels of abstraction should be translated into current-abstraction form so that higher levels of abstraction don't need to know about the lower levels, even purely for exception handling.

However, the "principle of leaky abstractions" is an issue. Some exceptions cannot be translated to a form that makes sense within the next layer of abstraction.

A networked filesystem related exception is a simple example. A network failure cannot be expressed in terms that make sense to a "file" abstraction or, if it does, that abstraction hasn't really fully abstracted away all the details relating to the implementation of file handling.

A network failure would therefore leak out of the underlying network abstraction, and must therefore be a cross-cutting concern within the rest of the code.

This isn't unique to exceptions, though. All those return-value error codes for file APIs that aren't really related to the file abstraction, but instead detail hard-disk or network or whatever failures are the same thing in a different form, implying that hard-disk failures and network failures etc are cross-cutting concerns irrespective of how those failures are reported.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.