1
\$\begingroup\$

I call several WebServices which return each a different exception type:

try {
   //calling first WS1 here
} catch (my.package1.FaultWS_Exception e) {
        StringBuilder sb = getMessageFromException(e);
        log(sb);
}

try {
   //calling first WS2 here
} catch (my.package2.FaultWS_Exception e) {
        StringBuilder sb = getMessageFromException(e);
        log(sb);
}

my getMessageFromException simply returns a pretty printed message from the exception.

But as my exceptions are in different packages (each method is in a different WS), I had to create different getMessageFromException() functions for each exception:

private StringBuilder getMessageFromException(my.package1.FaultWS_Exception e) {
    StringBuilder sb = new StringBuilder();
    if (e.getFaultInfo() != null) { //returns my.package1.FaultWS
        sb.append(e.getFaultInfo().getDescfault());
        sb.append("\n");
        sb.append(e.getFaultInfo().getCodefault());
        sb.append("\n");
    } else if (e.getMessage() != null) {
        sb.append(e.getMessage());
        sb.append("\n");
    }
    return sb;
}

private StringBuilder getMessageFromException(my.package2.FaultWS_Exception e) {
    StringBuilder sb = new StringBuilder();
    if (e.getFaultInfo() != null) { //returns my.package2.FaultWS
        sb.append(e.getFaultInfo().getDescfault());
        sb.append("\n");
        sb.append(e.getFaultInfo().getCodefault());
        sb.append("\n");
    } else if (e.getMessage() != null) { 
        sb.append(e.getMessage());
        sb.append("\n");
    }
    return sb;
}

This code looks very ugly and a bit repetitive (I have 4 different signatures so far), is there a way to refactor it ? knowing that the Exceptions are defined the same, except from the package name.

\$\endgroup\$
0

2 Answers 2

2
\$\begingroup\$

If the faultInfo properties are identical for every case, you could use reflection:

try {
   //calling first WS1 here
} catch (my.package1.FaultWS_Exception e) {
        StringBuilder sb = getMessageFromException(e, e.getFault());
        log(sb);
}

try {
   //calling first WS2 here
} catch (my.package2.FaultWS_Exception e) {
        StringBuilder sb = getMessageFromException(e, e.getFault());
        log(sb);
}

...

private StringBuilder getMessageFromException( Exception e, Object faultInfo )
{
    StringBuilder sb = new StringBuilder();
    if ( faultInfo != null )
    {
        FaultInfo genericFault = asGenericFault(faultInfo);
        sb.append( genericFault .getDescfault() );
        sb.append( "\n" );
        sb.append( genericFault .getCodefault() );
        sb.append( "\n" );
    }
    else if ( e.getMessage() != null )
    {
        sb.append( e.getMessage() );
        sb.append( "\n" );
    }
    return sb;
}

private FaultInfo asGenericFault( Object fault )
{
    try
    {   
        Class<? extends Object> faultType = fault.getClass();
        String descfault = (String) faultType.getMethod( "getDescfault").invoke( fault );
        String codefault = (String) faultType.getMethod( "getCodefault").invoke( fault );

        return new FaultInfo(descfault, codefault);
    }
    catch ( Exception e )
    {
        throw new IllegalArgumentException( "expected a type with public getDescfault() and getCodefault() methods but got: " + fault, e );
    }
}

FaultInfo would be a simple Java Bean with the 2 properties you need.

\$\endgroup\$
0
3
\$\begingroup\$

Simply use one method for all type of Exceptions.

Make it public static and move into a utility class.

public static StringBuilder getMessageFromException(Exception e){...}

Why do you need overloaded methods for different type of Exceptions?

User defined Exceptions are also subtype of Exception itself.


--EDIT--

create an interface for all your custom exceptions having getFaultInfo() method.

interface MyFaultWS {} // marker interface
class FaultWS implements MyFaultWS {} // do it for both the packages

interface FaultInfoException {FaultWS getFaultInfo();}

// do it for both the packages
class FaultWS_Exception extends Exception implements FaultInfoException {

    @Override
    public FaultWS getFaultInfo() {
        return ...; // return your package specific exception
    }
} 

Finally use

public static StringBuilder getMessageFromException(FaultInfoException e){...}
\$\endgroup\$
6
  • \$\begingroup\$ Thanks for the answer. I wouldn't be able to call e.getFaultInfo() as it doesn't exist in Exception. And also Exception is not really a tag relevant to this question :) \$\endgroup\$ Commented May 6, 2014 at 22:07
  • \$\begingroup\$ Have a look at my updated post. \$\endgroup\$
    – Braj
    Commented May 6, 2014 at 22:24
  • \$\begingroup\$ Finally you can do one thing extract the part that is common in all the methods and put in a separate method to reduce the redundant code. \$\endgroup\$
    – Braj
    Commented May 6, 2014 at 22:56
  • \$\begingroup\$ what's the part that is common in that particular case? \$\endgroup\$ Commented May 6, 2014 at 23:27
  • \$\begingroup\$ I think only else part is common. \$\endgroup\$
    – Braj
    Commented May 6, 2014 at 23:28

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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