You are viewing a plain text version of this content. The canonical link for it is here.
Posted to site-dev@james.apache.org by Apache Wiki <wi...@apache.org> on 2010/11/19 15:08:58 UTC

[James Wiki] Update of "HandlingExceptions" by ChanochWiggers

Dear Wiki user,

You have subscribed to a wiki page or wiki category on "James Wiki" for change notification.

The "HandlingExceptions" page has been changed by ChanochWiggers.
The comment on this change is: Somewhat pernickity language editing, particularly to improve reading flow, and a few formatting changes..
http://wiki.apache.org/james/HandlingExceptions?action=diff&rev1=5&rev2=6

--------------------------------------------------

  ----
  '''Administrative Control'''
  
- Prior to the James 2.2.0a5 test build, the Mail Administrator was unable to control exception management, and may need to, as the Administrator is the only person knowing if matching because of an exception is the correct application domain semantic.  In 2.2.0a5 we added a mechanism (the "onException") that provides administrative control, optionally coding (the attribute values are case insensitive):
+ Prior to the James 2.2.0a5 test build, the Mail Administrator was unable to control exception management.
+ 
+ In 2.2.0a5 we added the following optional configurations, {{{ onMatchException }}} and {{{ onMailetException }}}:
  
  {{{ 
    <mailet match="..." class="..."
@@ -19, +21 @@

  
   *  noMatch          - do not match any recipient (return null) (for matchers only)
   *  matchAll         - match all recipients (for matchers only)
-  *  error            - send the mail object to the error processor
+  *  error            - send the mail object to the error processor. '''the default'''
   *  <aProcessorName> - send the mail object to the named processor (don't code the "<" and ">")
   *  ignore           - ignore the exception and continue in the current processor (for mailets only)
  
- The default is equivalent to code on{Match|Mailet}Exception="error", that means sending to the error processor, as has always been before 2.2.0a5.
+ This config.xml stanza catches any MessagingException thrown by the underlying matcher or mailet (these may embed any Throwable caught below), but if a RuntimeException or an Error flows up it will not be handled.  ''[Technical note: It is an open issue whether to catch RuntimeException or even Throwable.  Any comments?  See also Overview of Exception Handling in the Mailet Pipeline, below.]''
  
- This config.xml "code" catches any MessagingException thrown by the underlying matcher or mailet (that may embed any Throwable catched below), but if a RuntimeException or an Error flows up it will not be considered here.  ''[Technical note: It is an open issue whether to catch here also RuntimeException or even Throwable.  Any comments?  See also Overview of Exception Handling in the Mailet Pipeline, below.]''
+ ''My take on this would be that RuntimeException and Error are caused by problems that cutting across functional concern and should therefore be handled by configuration. Not sure of the solution - it seems like it perhaps should be a mechanism in its own right, but the above would work with the option of providing standard processors. Chanoch''
  ----
  '''An Example'''
  
  An example taken from a system using the James 2.3.0 build is the following:
  
  {{{ 
-          <!-- Check attachment extensions for possible viruses -->
+ <!-- Check attachment extensions for possible viruses -->
-          <!-- The "-z" option requests the check to be non-recursively applied -->
+ <!-- The "-z" option requests the check to be non-recursively applied -->
-          <!-- to the contents of any attached '*.zip' file. -->
+ <!-- to the contents of any attached '*.zip' file. -->
-          <mailet match="AttachmentFileNameIs=-d -z *.exe *.com *.bat *.cmd *.pif *.scr *.vbs *.avi *.mp3 *.mpeg *.shs"
+ <mailet match="AttachmentFileNameIs=-d -z *.exe *.com *.bat *.cmd *.pif *.scr *.vbs *.avi *.mp3 *.mpeg *.shs"
-                  class="Bounce" onMatchException="error">
+         class="Bounce" onMatchException="error">
-             <inline>heads</inline>
+     <inline>heads</inline>
-             <attachment>none</attachment>
+     <attachment>none</attachment>
-             <passThrough>false</passThrough>
+     <passThrough>false</passThrough>
-             <prefix>[REJECTED]</prefix>
+     <prefix>[REJECTED]</prefix>
-             <notice>
+     <notice>
+ 
  The Security Policy of XXX does not allow to forward messages containing attachments having any of the extensions .exe, .com, .bat, .cmd, .pif, .scr, .vbs, .avi, .mp3, .mpeg, .shs, therefore your message has been rejected.
  
- Please don't reply to this e-mail as it has been automatically sent by the antivirus system.
+ This email is system generated. Replies to it will be ignored.
  
  Regards, Postmaster XXX.YYY
  .....................................
+ 
-             </notice>
+     </notice>
-          </mailet>
+ </mailet>
  }}}
  
- The onMailetException attributes were coded because some malformed messages, typical of viruses, are causing some javax methods to throw exceptions; my choice was to consider the message in error, but it could be done differently, perhaps the first way using noMatch, and the second way sending the message to a special "may-contain-executables" processor, that bounces back a less "resolute" message.
+ The {{{ onMailetException }}} attributes were coded because some malformed messages, typical of viruses, are causing some javax methods to throw exceptions; my choice was to consider the message in error, but it could be done differently, perhaps the first way using {{{ noMatch }}}, and the second way sending the message to a special "may-contain-executables" processor, that bounces back a less "resolute" message.
  ----
  '''Overview of Exception Handling in the Mailet Pipeline'''
  
- To recall (for the non Java programmers), here is the class hierarchy of Throwable:
+ For the non Java programmers, here is the class hierarchy of Throwable:
  
  {{{ 
  Throwable
@@ -68, +72 @@

  		...
  	Error
  		...
-  }}}
+ }}}
  
  The major distinctions are (quoting from Sun Javadoc):
  
   *  "An Error is a subclass of Throwable that indicates serious problems that a reasonable application should not try to catch. Most such errors are abnormal conditions."
  
- A standalone program should just not catch it and terminate. A server application like James should catch it and, if "fatal" (i.e. of general scope and not just related to the processing of a single Mail object for example) should terminate, otherwise should recover as possible (for instance sending the offending/offended Mail object to the error processor) and continue.
+ A standalone program should terminate without catching it. A server application like James should catch it and, if "fatal" should terminate (i.e. if it is of general scope and not just related to the processing of a single Mail object), otherwise it should recover if possible and continue (for instance sending the offending/offended Mail object to the error processor).
  
   *  "The class Exception and its subclasses are a form of Throwable that indicates conditions that a reasonable application might want to catch."
  
  With the exclusion of RuntimeException (see below), an Exception arise when an un-anticipated "event", caused by "external agents" (like IO error) occurs that can and should be managed somewhere in the code stack.
  
- The "best practice" should consist in having the code catch the exception as down as possible in the code stack and take an appropriate action as specifically as possible. Such action can also consist, if appropriate, in rethrowing up the exception or in embedding in a new exception and throw it. The java compiler helps, compelling a class either to catch an exception if thrown from below (unless it is a RuntimeException) or to declare a "throws".
+ The "best practice" should consist in having the code catch the exception as close to the event as possible and take appropriate action as specifically as possible. Such action can also consist, if appropriate, in rethrowing the exception or in embedding it in a new exception which it throws. The java compiler helps with checked exceptions, compelling a method to catch the exception or to declare it in it's signature.
  
   *  "RuntimeException is the superclass of those exceptions that can be thrown during the normal operation of the Java Virtual Machine. A method is not required to declare in its throws clause any subclasses of RuntimeException that might be thrown during the execution of the method but not caught."
  
- It looks similar to Error above, but the key point here is that a RuntimeException is (or should be) a programming error: something that can be fixed in the code, as for example an IndexOutOfBoundsException that appropriate controls in the code can avoid.
+ It looks similar to Error above, but the key point here is that a RuntimeException is (or should be) a programming error: something that can be fixed in the code, as for example an IndexOutOfBoundsException that appropriate controls in the code can avoid. It is not desirable that the code deal with this type of error, as this would incorporate exceptions as part of the normal application flow. From James' perspective, however, it would be desirable to handle this in such a way that the user is buffered from the consequences. (is given a helpful message)
  
   *  MessagingException is "The base class for all exceptions thrown by the Messaging classes."
  
- Very generic.
+ Generic exception belonging to javax.mail which extends Exception (i.e. it is not a RuntimeException)
  
  The key point for James is that the Matcher and the Mailet interfaces declare respectively the match(Mail) and the service(Mail) methods as throwing MessagingException. So it is the communication channel for exceptions between mailets and matchers and the rest of James.
  
@@ -96, +100 @@

  
  The James developers, taken in a broad sense, can be considered as a coordinated group of people, and we can consider exception management in the James code as following the same guidelines (to improve/enforce/cleanup perhaps).
  
- The James code invokes matchers and mailets, that can be foreign code. So James must protect itself from a Throwable arising from below, from code that not necessarily follows all the rules.  Each matcher or mailet follows its own exception management rules (those in the James distribution should be coherent with the rest of the James code.
+ The James code invokes matchers and mailets, that can be foreign code. So James must protect itself from a Throwable arising from below from code that may not be following the rules.  Each matcher or mailet follows its own exception management rules (those in the James distribution should be consistent with the rest of the James code.
  
- At this level the following is anyhow always true: as said before, the Matcher and the Mailet interfaces declare respectively the match(Mail) and the service(Mail) methods as throwing MessagingException. As a consequence, when a matcher or a mailet gets an exception while processing a Mail object (not during initialization - this is another story) it can do the following things: if the exception is a MessagingException it can either catch it or let it flow up (to LinearProcessor, part of James' spool management); if the exception is any other Exception (but not some kind of RuntimeException), the java compiler forces the programmer to catch it somewhere and either take the appropriate action, or to embed it in a new MessagingException and and throw it up.
+ At this level the following is always true: as said before, the Matcher and the Mailet interfaces declare respectively the match(Mail) and the service(Mail) methods as throwing MessagingException. As a consequence, when a matcher or a mailet gets an exception while processing a Mail object (though not during initialization - that is another story) it can do the following things: if the exception is a MessagingException it can either catch it or let it flow up (to LinearProcessor, part of James' spool management); if the exception is any other checked Exception, the java compiler forces the programmer to catch it and process it, including the option of embedding it in a new MessagingException to throw upwards.
  
- In the middle stays the administrator of the James server instance deployed, that coding his config.xml decides to use or not a specific matcher or mailet, and is coding a kind of "program" using <mailet match="..." class="...">, equivalent to if (...) {...}. As said above, since 2.2.0a5 he is able to exercise some control using the "onException" mechanism.
  ----
  '''Other error conditions'''
  
- Now, what happens if a RuntimeError flows up? It will not be catched at config.xml level, but JamesSpoolManager.process(MailImpl) will catch it and have the Mail object sent to the error processor.
+ If a RuntimeError flows up, it will not be caught at config.xml level, but JamesSpoolManager.process(MailImpl) will catch it and send the Mail object to the error processor.
  
- Finally, what happens if an Error flows up? Before the James 2.2.0a7 test build, it was catched a level up in the stack, in JamesSpoolManager.run(), which reported the exception and left the message in the spool.  This could lead to some problem conditions.
+ In case of an Error, before the James 2.2.0a7 test build it was caught a level up in the stack, in JamesSpoolManager.run(). This then reported the Throwable and left the message in the spool.  This could lead to some problem conditions.
  
- In James 2.2.0a7 and later JamesSpoolManager.process(MailImpl mail) will catch any Throwable, and have the Mail object sent to the error processor.  JamesSpoolManager.run() still can catch Throwables that flow up from other spool related operations, but will no longer receive from below any Throwable originating from matchers or mailets.
+ In James 2.2.0a7 and later, JamesSpoolManager.process(MailImpl mail) catches any Throwables, and sends the Mail object to the error processor.  JamesSpoolManager.run() can still catch Throwables that flow up from other spool related operations, but will no longer receive from below any Throwable originating from matchers or mailets.
  

Unsubscribe

Posted by "Berenson, Dana" <Da...@FMR.com>.