mardi 15 novembre 2011

Idea to manage methods' result and exceptions

I ofen had to think about how I could manage well methods' result as well as exceptions.
To be honest, I'm not a big fan of exceptions. I think exceptions and their management put a lot of noise in the code. With exceptions, we have our try / catch blocks (sometimes those blocks are nested) and we must deal with variable declarations to be sure they are in the good scope.

Then, I've begun to think about a way to manage errors and results of my methods. First, I thought to add an error param in each method. This way is often used in C programming. But now, I develop in Groovy and for me. this way is a kind of anachronism. Anothier way was to return null for error and the result when method is successull. But in this case, we don't have granularity to manage different errors. And sometimes, null is the good result.

After pieces of time, I said to myself: "Why don't use some computing principles as current as HTTP and login framework like log4j ?". Thus, yesterday I began to write a class may be used to return information from method calls.

I'm explaining my thoughts. First, I take from log4J the notion of result's level. For a method, I consider those levels:
  • OK (method is successfull and the caller can trust in the result)
  • WARNING (a result has been given but something were weird)
  • ERROR (method has failed)
  • FATAL (big problem with the method, like an exception)
To retrieve the status level of my method call, I want to use some getters like isOk(), isWarning(), ...

From HTTP, I take the result code number and a message. The result code is an integer and the message is a string. It's simple and efficient. The developer saves into these properties information about result. The message could even be a code used by a i18n message bundle for instance.

After, I have to get the result. This can be a non-type property (I'm into Groovy mind) named value.

And last, I want to use insance of my class like the real method's result. So, I must to catch calls to my class and delegate them to the result object.

Here, a Groovy code showing my idea:

class Response implements GroovyInterceptable {
    public final static NL = 0
    public final static OK = 100
    public final static WR = 200
    public final static ER = 300
    public final static FT = 400
    
    Integer status = NL
    String message
    Integer returnCode
    def value
    
    
    Boolean isResponse() { true }
    
    Boolean isOk() { status == OK }
    Boolean isWarning() { status == WR }
    Boolean isError() { status == ER }
    Boolean isFatal() { status == FT }    
    
    def invokeMethod(String name, args) {
        def result
        if (name in ['isOk', 'isWarning', 'isError', 'isFatal']) {
            def metaMethod = metaClass.getMetaMethod(name, args)
            result = metaMethod.invoke(this, args)
        } else {
            def metaMethod = value.metaClass.getMetaMethod(name, args)
            result = metaMethod.invoke(value, args)
       }
       
        return result
    }
} 
 
// A method to test my result class
def add(x, y) {
    new Response(status: Response.OK, message: "$x plus $y", returnCode: 0, value: x + y)
} 
 
// Some tests
def result = add(12, 8)
assert result.isOk()
assert result == 20
assert result + 5 == 25
println result.message
println result.status


With the Groovy code above,  I can manage all the cases which can happen from method calls.

What do you think about that ? I wait for any feedbacks and other ideas to improve my method result class. If you want, you can write implementation into other languages.

Aucun commentaire:

Enregistrer un commentaire