• Welcome to KonaKart Community Forum. Please login or sign up.
 

exception handling

Started by rula, July 30, 2008, 01:39:09 pm

Previous topic - Next topic

rula

Hi Konakarts,
I don't understand the complete exception handling of konakart, but I estimate that it is very good.
NowI have a i18n problem with exceptions and messages (errors).
I need a message-key but a message text (in the false language) is delivered.
e.g.

in NewAddrSubmitAction.java:

try
{
  kkAppEng.getCustomerMgr().fetchZonesForRegistration(addr.getCountryId());
}catch (KKException e1)
{
  return mapping.findForward(super.handleException(request, e1));
}
  return getForward(mapping, request, e, "com.konakart.app.KKInvalidZoneException",
  Constants.invalidZone, "ApplicationError");
}


delivered in NewAddrBody.jsp:

Please select a state from the States pull down menu.

and in requestScope:

org.apache.struts.action.ERROR  {org.apache.struts.action.GLOBAL_MESSAGE=[exception.null.message[Please select a state from the States pull down menu.]]} 

How can I get a usable errorKey form this exception for translation in the jsp. (<html:messages...) ?

regards, rula

pete


rula

Hi pete,

I would call the getForward methode with my translated message text instead of 'Constants.invalidZone'  for this exception.
Is this the way to reach a locale sensitive message when this exception occurs? 

return getForward(mapping, request, e, "com.konakart.app.KKInvalidZoneException",
Constants.invalidZone, "ApplicationError");

regards, rula

pete

In our current version (not released yet) we have the following code:

                return getForward(mapping, request, e, "com.konakart.app.KKInvalidZoneException",
                        getCatMessage(request, "register.customer.body.invalid.zone"),
                        "ApplicationError");

rula

Hi pete,

I do something like this:

/*             
return getForward(mapping, request, e, "com.konakart.app.KKUserExistsException",
                  Constants.userExists, "ApplicationError");
*/
String message = getResources(request).getMessage(getLocale(request), "register.customer.body.user.exists");
return getForward(mapping, request, e, "com.konakart.app.KKUserExistsException",
                  message, "ApplicationError");

in:
CustomerRegistrationSubmitAction.java,
NewAddrSubmitAction.java and
EditAddrSubmitAction.java.

I have looked for all ApplicationErrorrs that I have found in Custom Actions.

Struts declarativ exception handling over struts-config could be nice for me.
Is it possible and good to catch the ApplicationErrors over global or local exception tags and remove try catch blocks?

i18n is not so easy in konakart, many property files are not enough.

regards, rula


pete

QuoteI do something like this:

/*             
return getForward(mapping, request, e, "com.konakart.app.KKUserExistsException",
                  Constants.userExists, "ApplicationError");
*/
String message = getResources(request).getMessage(getLocale(request), "register.customer.body.user.exists");
return getForward(mapping, request, e, "com.konakart.app.KKUserExistsException",
                  message, "ApplicationError");

in:
CustomerRegistrationSubmitAction.java,
NewAddrSubmitAction.java and
EditAddrSubmitAction.java.

We've actually made the same changes for the next release  :)

QuoteStruts declarativ exception handling over struts-config could be nice for me.

Why would you prefer this ? Since you have all of the code you could implement it.

QuoteIs it possible and good to catch the ApplicationErrors over global or local exception tags and remove try catch blocks?

Not sure what you mean here.

Quotei18n is not so easy in konakart, many property files are not enough.

With those three changes to the action classes isn't the problem fixed ? All messages are now taken from the message catalog. They were taken from the message catalog even before the fix but were cached and so not changed if you decided to change the language of your UI.

rula

Hi pete,
I saw something like this and tested it.

in struts-config:
<action path="/login"
        name="userForm"
        scope="request"
        input="login"
        type="de.rula.dga.action.UserAction"
        parameter="dispatch">
  <exception  type="de.rula.dga.UnknownUserException"
              key="errors.unknownUser"
              path="login"/>           
  <exception  type="de.rula.dga.InvalidPasswordException"
              key="errors.invalid.Password"
              path="login"/>                             
  <forward name="success" path="home"/>
</action>

in UserService:
public User authenticate(String userName, String password)
throws Exception{
 
  User user = userDao.getUser(userName);
  if(user == null){
    throw new UnknownUserException();
  }
 
  boolean validPassword = user.passwordMatch(password);
  if(!validPassword){
    throw new InvalidPasswordException();
  }
 
  List roles = userDao.getRoles(userName);
  user.setRoles(roles);

  return user;
}

in UserAction:
public ActionForward login( ActionMapping mapping,
                            ActionForm form,
                            HttpServletRequest request,
                            HttpServletResponse response)
  throws Exception{
  if(log.isDebugEnabled())
    log.debug("login");
 
  HttpSession session = request.getSession();
 
  DynaValidatorActionForm userForm = (DynaValidatorActionForm)form;
  User user = (User)FormUtils.getFormValues(userForm, this, mapping, request); 
  user = userService.authenticate(user.getUsername(), user.getPassword());
 
  session.setAttribute("user", user);
 
  return mapping.findForward(Const.FORWARD_SUCCESS);
}

I mean, I have not to handle the exceptions in the actions, but configure it in struts(-config).

I am only a small struts user and no developer and don't understand the details of caching message resources. regards, rula

pete

Sure, it's an alternative way of achieving the same goal. Although this is a feature of struts, I don't really see the advantage in our case since it isn't really something that you will want to change. Personally I prefer to keep the exception handling in the Java domain where I find it easier to read, rather than in an XML file.

By the way, my advice is not to tell the user whether they have made a mistake in the userId or in the password . This could give them valuable information and help them to hack the system. :(

rula

Hi pete,

okay, this with the exception was only a idea a my code is indeed not so secure. :o
regards, rula

rula

Hi pete,
Quote
With those three changes to the action classes isn't the problem fixed ? All messages are now taken from the message catalog. They were taken from the message catalog even before the fix but were cached and so not changed if you decided to change the language of your UI.


1.extended PropertyMessageResources.java
2.extended PropertyMessageResourcesFactory.java
3.call reload methode in SetLocaleAction.java
4.replaced <message-resources/> tag

1.

public class ReloadablePropertyMessageResources
extends PropertyMessageResources{

public ReloadablePropertyMessageResources(ReloadablePropertyMessageResourcesFactory factory, String config){
super(factory, config);
}

public ReloadablePropertyMessageResources(ReloadablePropertyMessageResourcesFactory factory, String config, boolean returnNull){
super(factory, config, returnNull);
}

public synchronized void reload(){
locales.clear();
messages.clear();
formats.clear();
}
}


2.

public class ReloadablePropertyMessageResourcesFactory
extends PropertyMessageResourcesFactory{

public MessageResources createResources(String config){
return new ReloadablePropertyMessageResources(this, config, this.getReturnNull());
}
}


3.

((ReloadablePropertyMessageResources)getResources(request)).reload();


4.

  <!--
  <message-resources parameter="Messages" null="false"/>
  -->
  <message-resources parameter="Messages" com.konakart.ReloadablePropertyMessageResourcesFactory"/>


It seems to work, but I am not sure.
The clearing of the resources hashmaps in the reload methode seems to solve the caching problem.
Is this okay!?

regards, rula

pete

I don't think you need to go to that level of complexity. e.g. Instead of:

return getForward(mapping, request, e, "com.konakart.app.KKUserExistsException",
                        Constants.userExists, "ApplicationError");

you need:

return getForward(mapping, request, e, "com.konakart.app.KKUserExistsException",
                        getCatMessage(request, "register.customer.body.user.exists"),
                        "ApplicationError");

The caching problem exists because Constants.userExists used to contain the message and this static variable was loaded at startup and never refreshed if a user decided to change language.