I have the following Groovy class:
@Slf4j
class WidgetService {
WidgetDao widgetDao = new WidgetDao()
createWidget(String name, int type) {
try {
widgetDao.createWidget(name, type)
} catch(WidgetException wexc) {
log.error(wexc)
int x = doFizz()
long y = doBuzz(x)
determineHowToHandle(y)
}
}
Widget getWidgetById(Long id) {
try {
widgetDao.getWidgetById(id)
} catch(WidgetException wexc) {
log.error(wexc)
int x = doFizz()
long y = doBuzz(x)
determineHowToHandle(y)
}
}
Widget getWidgetByName(String name) {
try {
widgetDao.getWidgetByName(name)
} catch(WidgetException wexc) {
log.error(wexc)
int x = doFizz()
long y = doBuzz(x)
determineHowToHandle(y)
}
}
def deleteWidget(Widget w) {
try {
widgetDao.deleteWidget(w)
} catch(WidgetException wexc) {
log.error(wexc)
int x = doFizz()
long y = doBuzz(x)
determineHowToHandle(y)
}
}
...dozens of more methods with *exact* same catch block
}
As you can see I have a lot of duplicate, boilerplate code in my try-catch blocks. It would be nice if I could define a closure or some sort of AOP-based handler just pass the widgetDao
method-of-interest into the closure/handler as a lambda or something similar:
def createWidgetClosure = { it =>
widgetDao.createWidget(it.name, it.type)
}
def getWidgetByIdClosure = { it =>
widgetDao.getWidgetById(it.id)
}
def tryCatchClosure = { closure =>
try {
closure()
} catch(WidgetException wexc) {
log.error(wexc)
int x = doFizz()
long y = doBuzz(x)
determineHowToHandle(y)
}
}
So that my `WidgetService could then look something like this:
@Slf4j
class WidgetService {
WidgetDao widgetDao = new WidgetDao()
createWidget(String name, int type) {
tryCatchClosure(createWidgetClosure())
}
Widget getWidgetById(Long id) {
tryCatchClosure(getWidgetByIdClosure())
}
...dozens of more methods with *exact* same catch block
}
Is this possible? If so, how?
You can simply do as below by using tryCatchClosure
what you have now. You can even make tryCatchClosure
a method which takes Closure
as a parameter.
class WidgetService {
WidgetDao widgetDao = new WidgetDao()
def tryCatchClosure(Closure closure) {
try {
closure()
} catch(WidgetException wexc) {
log.error(wexc)
int x = doFizz()
long y = doBuzz(x)
determineHowToHandle(y)
}
}
createWidget(String name, int type) {
tryCatchClosure {
widgetDao.createWidget(name, type)
}
}
Widget getWidgetById(Long id) {
tryCatchClosure {
widgetDao.getWidgetById(id)
}
}
Widget getWidgetByName(String name) {
tryCatchClosure {
widgetDao.getWidgetByName(name)
}
}
def deleteWidget(Widget w) {
tryCatchClosure {
widgetDao.deleteWidget(w)
}
}
// ...dozens of more methods with *exact* same catch block
}
Or you can also intercept each method call on WidgetDao
by overriding invokeMethod
method on its metaClass and handle exception (try/catch). Similar to this.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With