Page 1 of 2 12 LastLast
Results 1 to 10 of 11

Thread: How to handle business exceptions and html form re-display

  1. #1
    Join Date
    Nov 2006
    Location
    Brighton, UK
    Posts
    14

    Default How to handle business exceptions and html form re-display

    All,

    I would like some advice on how to handle business exceptions thrown as a result of an html form submission.

    Previously in SWF 1.x I would declare a method to process the form submission that would have a return type of Event. If the method call succeeded it would return success() and the flow would transition as required. If it failed an error message would be created and added to the errors object in the RequestContext, the method would return error() and the flow would transition back to the calling page .

    The below code snippets shows an example of the <action-state> that defines the method a call and the transitions and the method called from the action.


    Code:
    <action-state>
    	<action bean="searchBean" method="findText"/>
    	<transition on="success" to="results"/>
    	<transition on="error" to="search"/>	
    </action-state>

    Code:
    public Event findText(RequestContext ctx)
    
    	String text = null;
    	try {
    		text  = searchForText();
    	} catch(AbcNotFoundException e) {
    		getFormErrors(ctx).reject("text.error.key", "No text found default message");
    		return error();	
    	}
    
    	ctx.getFlashScope().put("text", text);
    	return success();	
    }
    I will crack open the 1.x source and have a look at what is going on to see how I can replicate this in SWF 2.0.x but in the mean time would be very interested to know if there is an established "pattern" for handling this situation in SWF 2.0.x

    You help greatly appreciated.
    Use the API Luke...

  2. #2
    Join Date
    Aug 2004
    Location
    Melbourne, FL
    Posts
    2,794

    Default

    I would seriously consider handling this by executing an action within a view-state transition block that processes your form submission event after successful model binding and validation. This action can then use the MessageContext API to record error messages if necessary, and return false to prevent the transition from executing after an error condition [thus causing the view to re-render].

    Keith
    Keith Donald
    Core Spring Development Team

  3. #3
    Join Date
    Sep 2007
    Location
    Brooklyn, NY
    Posts
    20

    Default Solution not workable for some use cases

    Keith, what if the the business logic only executes after all view states have completed?

    One case I have is where a few views are used to collect order information, then an order summary is displayed and only after that view is the order submitted (including authorizing payment for the order). If the payment authorization process throws an exception you want to display the payment view state again with an error about the card being invalid.

    This gets even more complicated if you use sub-flows.

  4. #4
    Join Date
    Nov 2006
    Location
    Boston, MA
    Posts
    303

    Default

    Quote Originally Posted by yellowpinky View Post
    The below code snippets shows an example of the <action-state> that defines the method a call and the transitions and the method called from the action.


    Code:
    <action-state>
    	<action bean="searchBean" method="findText"/>
    	<transition on="success" to="results"/>
    	<transition on="error" to="search"/>	
    </action-state>

    Code:
    public Event findText(RequestContext ctx)
    
    	String text = null;
    	try {
    		text  = searchForText();
    	} catch(AbcNotFoundException e) {
    		getFormErrors(ctx).reject("text.error.key", "No text found default message");
    		return error();	
    	}
    
    	ctx.getFlashScope().put("text", text);
    	return success();	
    }
    Yellowpinky,

    I am not sure why you are using exceptions in the example above - in the first place. Exceptions should be used for exceptional conditions, i.e. true errors. It looks like you are using them to implement business logic, which is a very bad idea. In your example, you basically need to check if your search returns an empty string. Instead of returning an empty string, your search method throws an exception if some text is not found. It is really, really wrong. That said, the whole idea of "business exceptions", or "recoverable exceptions", is pretty much a bogus concept that has been used for years by the supporters of checked exceptions in Java to justify their existence. You either have an error condition (which you must always allow/force to propagate - uninterrupted and unaltered - to a handler that is designed to handle abnormal error conditions a.k.a. exceptions) or you just implement the business logic - without throwing exceptions - to handle legitimate use cases such as the one you are describing: text not found. In each of such cases (as you describe), you may generate an appropriate SWF event that would transition to the appropriate (possibly, distinct) view. Remember: each of these cases are your legitimate use cases, not exceptions. So, you must design for them, not just react to them as "unexpected" errors.

    HTH,
    Constantine

  5. #5
    Join Date
    Nov 2006
    Location
    Brighton, UK
    Posts
    14

    Default

    Keith,

    Thank you for your advice. I will do it that way.

    Constantine,

    I have to say that I used to agree with your view on when, where and why exceptions should be thrown but now see things differently.

    The following article puts forwards a good case, far more eloquently that I could, for throwing business (contigency) exceptions as per my example. Its worth a read. - see the dev2dev.bea.com/pub/a/2006/11/effective-exceptions.html

    Also the Spring framework uses the same concept in a number of its classes - see: spring/docs/2.5.x/api/index.html?org/springframework/jdbc/core/JdbcTemplate.html - and the queryForObject() method for example.


    Thanks

    YP
    Use the API Luke...

  6. #6
    Join Date
    Nov 2006
    Location
    Boston, MA
    Posts
    303

    Default

    Quote Originally Posted by yellowpinky View Post
    Constantine,

    I have to say that I used to agree with your view on when, where and why exceptions should be thrown but now see things differently.

    The following article puts forwards a good case, far more eloquently that I could, for throwing business (contigency) exceptions as per my example. Its worth a read. - see the dev2dev.bea.com/pub/a/2006/11/effective-exceptions.html

    Also the Spring framework uses the same concept in a number of its classes - see: spring/docs/2.5.x/api/index.html?org/springframework/jdbc/core/JdbcTemplate.html - and the queryForObject() method for example.


    Thanks

    YP
    YP,
    I think you may be misinterpreting things a bit here. Here's the quote from the Javadoc for queryForObject(...):

    Code:
    Throws:
        IncorrectResultSizeDataAccessException - if the query does not return exactly one row, or does not return exactly one column in that row 
        DataAccessException - if there is any problem executing the query
    What it means is that these exceptions are thrown when - clearly - an error occurs retrieving the data. The correct functionality here means that a valid object, and only one object - must be retrieved. The first exception indicates that, perhaps, some data integrity violation takes place, etc. I have seen this happen in database schemas that did not use proper constraints and would allow - -mistakenly - insertion of duplicates, etc. QueryFor... methods are used exactly in the cases where the presense of more or less than one object in the data store must be considered an error. Generally, exceptions thrown by JdbcTemplate are RTEs that wrap/convert the checked SqlExceptions that may be thrown underneath the Spring layer, so it is a necessity.

    You would also see that many of Spring's overridable callback methods are defined with "throws Exception" in their signatures. That is not because Spring approves the use of checked exceptions but to ensure that any exception (checked or unchecked) thrown inside the overriding custom method is covered and will be taken care of by the framework.

    Generally, there may be cases when you would want to use an exception instead of returning an empty object - to underline the fact that such result may never be valid. For example, an object constructor should throw an invalid input RT exception if no valid instances of the class may ever exist with the provided data. Exceptions are expensive and inefficient for business logic implementation. HTH.
    Thanks,
    Constantine

  7. #7
    Join Date
    Nov 2006
    Location
    Brighton, UK
    Posts
    14

    Default

    Constatine,

    Putting things slightly more tactfully. I agree that the answers to these issues are down to interpretation and ours obviously differ.

    I have not found any documentation that says queryFor.. methods should only be used for querying a database when the data item is guaranteed to exist and if it doesn't a fundamental system exception must have occurred (if there is please direct me to it as I am genuinely interested). As an aside -from a design standpoint you could argue that this type of exceptional occurrance is a good candidate for a RuntimeException. As it may not be reasonable to expect a system to recover when its underlying database constraints have not been violated.

    Returning to my original post I would be grateful if anyone has any examples of handling this errors scenario. The reason is that I am using an annotated controller and the method returns a specific type not a boolean status flag. If I do implement the boolean how do I make the current returned value available to webflow?

    I was under the impression that I would not have to write webflow specific actions in SWF2.0.x. Perhaps I have got the wrong end of the stick?


    Thanks

    yp
    Use the API Luke...

  8. #8
    Join Date
    Aug 2004
    Location
    Melbourne, FL
    Posts
    2,794

    Default

    Martin,

    Why couldn't you apply this solution to your order summary view-state? You can always define a dedicated action-state that does the same thing of course--invoke an action that calls your service, handles the exception by recording errors, and returns error() (or false) which results in a transition back to a view to revise.

    Keith
    Keith Donald
    Core Spring Development Team

  9. #9
    Join Date
    Nov 2006
    Location
    Boston, MA
    Posts
    303

    Default

    Quote Originally Posted by yellowpinky View Post
    I have not found any documentation that says queryFor.. methods should only be used for querying a database when the data item is guaranteed to exist and if it doesn't a fundamental system exception must have occurred (if there is please direct me to it as I am genuinely interested). As an aside -from a design standpoint you could argue that this type of exceptional occurrance is a good candidate for a RuntimeException. As it may not be reasonable to expect a system to recover when its underlying database constraints have not been violated.
    Well, I'd think the fact that the methods indeed throw a runtime exception when none or more than one objects are returned in the result set should be a hint, shouldn't it? So, I am not sure how much more documentation on the subject we really need. Also, I think that every exceptional condition is a candidate for a RTE, since no API should make any assumption whatsoever regarding how - in which context - it will be used in a client application. RTEs represent the true concept of exceptions, the mechanism that helps the error to propagate to a dedicated handler without affecting any business logic between error sources and handlers. That ensures safety, code clarity, ease of maintenance. The introduction of checked exceptions in Java should be considered a crime!

    As for the original question, I agree with Keith. In similar cases, instead of the next view state I usually introduce an action state to which the view transitions to. That action state evaluates different possible conditions (use cases, and, possibly checks for certain errors) and issues events accordingly. The definition for that action state would contain transitions on those events - to the appropriate views. Or the action state can just collect errors and direct to the next view - in Martin's scenario.

    Thanks,
    Constantine
    Last edited by constv; May 29th, 2008 at 04:17 PM.

  10. #10
    Join Date
    Nov 2006
    Location
    Brighton, UK
    Posts
    14

    Default

    Keith,

    I will look into this further.

    Constantine,

    Agree we not need to labour this point. However, for the sake of those who may read this post in the future I thinks its worth including the below snippets from a Q&A session with Springs Founder that were posted on the tss site. As it is at odds with your assertions.

    /news/thread.tss?thread_id=17740#74095[/url]

    Checked exceptions
    Posted by: Pal Hoye on February 13, 2003 in response to Message #74061
    Hi,
    On page 127 in your book you have a list of guidelines for choosing between checked and unchecked exceptions. The first one mentions to throw a checked exception if the exception is essentially a second return value for the method.

    My question is wether it is wise to throw an exception in this case at all? Since the exception handling mechanism in Java is known to have a significant overhead, many developers believe that it should only be thrown when something that should not have occured did occur (something horrible wrong as you state it) and that in other cases it is better to detect the error in other ways.

    I know you wrote about this in your book, but I was wondering what you think about the overhead for using exceptions (for performance reasons) when it really is just another business rule you are implementing when you catch the exception.

    Thanks for sharing your knowledge in this thread.

    Message #74114 Post replyPost reply Go to topGo to top
    Checked exceptions
    Posted by: Rod Johnson on February 14, 2003 in response to Message #74095
    I think an alternative return value is an idiomatic use of checked exceptions in Java. This allows the effective return of a completely different object in scenarios that must be handled by business logic in the caller.

    The overhead of catching exceptions will vary with JVM. In some JVMs, it's as cheap to catch an ArrayIndexOutOfBoundsException as to use a proper loop (although of course this is not good programming practice).

    But in cases where business logic is involved, performance isn't normally a consideration. As I stress in the book, it's important to avoid unnecessary optimizations. In a deeply nested loop, it might make sense to be wary of exception handling. In the signature of a business method, the performance of the necessary exception handling is a non-issue.

    Regards,
    Rod

    Thanks

    yp
    Use the API Luke...

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •