Duplicate try-catch blocks with Groovy with closure?

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 duplicates, template code in try-catch blocks. It would be nice if I could define a closure or some kind of AOP-based handler, just pass the widgetDao method of interest to the closure / handler like lambda or something like that:

 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 my "WidgetService" might 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 it possible? If so, how?

+5
source share
1 answer

You can simply do as shown below using tryCatchClosure what you have now. You can even make a tryCatchClosure method that 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 every method call on WidgetDao by overriding the invokeMethod method on your metaclass and handle the exception (try / catch). Like this .

+5
source

Source: https://habr.com/ru/post/1204838/


All Articles