groovy-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Edinson E. Padrón Urdaneta <edinson.padron.urdan...@gmail.com>
Subject Re: Is it possible to implement in the language an `else` block in exception handling?
Date Mon, 28 Sep 2015 16:55:10 GMT
​Hi, everyone. Thank you for your replays.

> If I understand you correctly, what you're proposing would look a bit
like this:
>
>   try {
>       mayThrow()
>   } catch (e) {
>       handleException(e)
>   } else {
>       try {
>           shouldNotThrowButOneNeverKnows()
>       } catch(e) {
>           handleExceptionInElse(e)
>       }
>   } finally {
>       cleanup()
>   }

That's absolutely correct.

> I have two questions:
>
> * `else` as a keyword implies that the `else` block is executed
> instead of another code block. What would that another block be?

Actually, it would be *blocks*, because the `else` block would be executed
instead of any `catch` block.

> * if `try` block is the last one in a method, it'll be evaluated as an
> expression and the result of the last expression inside try/catch is
> the method's return value. What would be the return value in your
> proposal?

I'll address this one with the following example:

def specialDivision(Integer a, Integer b) {
  try {
    a / b
  } catch (NullPointerException e) {
    "you didn't initialize correctly one of the arguments"
  } catch (ArithmeticException e) {
    "you can't divide by zero"
  } else {
    "everything went ok"
  }
}

assert specialDivision(10, null) == "you didn't initialize correctly one of
the arguments"
assert specialDivision(10, 0) == "you can't divide by zero"
assert specialDivision(10, 2) == "everything went ok"

I know this is a silly and very unpractical IRL example but I hope it shows
the idea I'm proposing. As you can see, the return value is the last
expression
of the `else` block if and only if none of the `catch` blocks were executed.

A more general example for further clarification:

try {
  // code that may throw exceptions

} catch (Exception1 e) {
  // code executed if an exception of type Exception1 was throw
} catch (Exception2 e) {
  // code executed if an exception of type Exception2 was throw
.
.
.
} catch (ExceptionN e) {
  // code executed if an exception of type ExceptionN was throw
} else {
  // code executed if none of the above `catch` blocks were executed (aka
the
  // code inside the try block didn't throw a exception at all)
} finally {
  // code that is always executed
}

Someone in SO suggested the following to simulate this behaviour:

def success = true

try {
  // code that may throw exceptions

} catch (Exception1 e) {
  success = false
  // code executed if an exception of type Exception1 was throw
} catch (Exception2 e) {
  success = false
  // code executed if an exception of type Exception2 was throw
.
.
.
} catch (ExceptionN e) {
  success = false
  // code executed if an exception of type ExceptionN was throw
} finally {
  // code that is always executed
}

if (success) {
  // code executed if none of the above catch blocks were executed (aka the
  // code inside the try block didn't throw a exception at all)
}

Even if this works I think it introduces a lot of visual noise to the code.
It's also error prone, you can forget to set the flag `success` to false
inside
one or more `catch` blocks. If you use a `return` statement inside the `try`
block the `if` block at the end will never be executed.

Mime
View raw message