przeciwieństwie do Javy, nie trzeba zadeklarować (zaznaczone) wyjątków, które są generowane przez metodę Groovy, bo jakieś niewypowiedziane sprawdzane wyjątki są owinięte w UndeclaredThrowableException.
Wydaje się sugerować, że Groovy okłady Wyjątki sprawdzane przez UndeclaredThrowableException, to nie jest przypadek. Jeśli usługa Grails zgłasza niezaznaczony wyjątek, wyjątek zostaje ostatecznie uszkodzony przez wyjątek UndeclaredThrowableException, ale jest to mechanizm java.lang.reflection i wystąpi tylko wtedy, gdy zaangażowana jest klasa proxy.
Tak się składa, ponieważ dotyczy to usługi Grails. Nie mam pewności, ile klas proxy jest dokładnie zaangażowanych, ponieważ istnieje co najmniej jeden: klasa, która obsługuje transakcję (wiosną).
Klasa zawinie dowolną metodę w usłudze za pomocą transakcji i wycofa transakcję po wystąpieniu wyjątku RuntimeException. Zarządzanie transakcjami wiosennymi domyślnie nie wycofuje się w przypadku sprawdzonego wyjątku.
Java
to sens w zwykły stary java, ponieważ deweloper będzie zobaczyć wyjątek w kodzie aplikacji i zostanie ostrzeżony, aby coś z tym zrobić. Jeśli programista jest sprytny, zajmie się wszystkimi wyjątkami w zakresie transakcji.Jeśli nie wycofa transakcji, zasadniczo mówi: "W tej sytuacji integralność danych dostarczona przez transakcję nie jest dla mnie ważna. Będę odzyskać od tego błędu w jakiś inny sposób”
Groovy
To nie ma sensu w świecie, ponieważ Groovy Groovy kompilator nie wymusza czynienia z wyjątkami. W efekcie traktuje Wyjątki dokładnie tak samo, jak Wyjątki RuntimeException.
Istnieje jednak zastrzeżenie: mechanizm odbicia widzi wyjątek zgłoszony przez serwer proxy, który nie znajduje się w metodzie podpisu oryginalnej usługi. Jest to możliwe, ponieważ:
- Groovy nie wymusza obsługę Wyjątki
- Sposób proxy zawsze można rzucać żadnych Throwable (sprawdź InvocationHandler JavaDoc)
Ponieważ mechanizm stosowany jest odbicie od Java musi być zgodny z regułami Java. Więc będzie musiał zawinąć wyjątek w RuntimeException, .. w tym przypadku wyjątek UndeclaredThrowableException.
Grails
Teraz robi się naprawdę trudne, ponieważ jeśli zadzwonić do metody usługi od kontrolera i występuje wyjątek. Zobaczysz dymek RuntimeException (z powodu ukrytego mechanizmu), ale twoja transakcja nie zostanie wycofana (z powodu jakiegoś ukrytego mechanizmu).
Takie zachowanie jest bardzo niebezpiecznejako deweloper naprawdę musi pamiętać, aby prawidłowo radzić sobie z wszelkimi wyjątkami (które kompilator nie pomogą) lub deweloper musi się upewnić, że wszelkie usługi jest odpowiednio poinstruowani z @Transactional (rollbackFor = Throwable).
Jest to problem z konstrukcją, który, jak sądzę, twórcy Grails przeoczyli, kiedy po raz pierwszy to zaprojektowali. Ale myślę, że domyślne zachowanie jest tak złe i tak niebezpieczne, że to naprawdę powinno zostać zmienione.
Cóż, potrzebuję sprawdzonych wyjątków w moim przypadku, ponieważ jest kilka aspektów, którymi muszę się zająć od API Stripe. Skończyło się na innej trasie, ponieważ muszę również rzucić wyjątek RuntimeException, aby moje transakcje zostały poprawnie wycofane. Zaznaczam twoją odpowiedź jako poprawną, ponieważ jest to właściwa odpowiedź na moje pytanie. Dzięki. – Gregg
Nie ma za co. BTW, możesz wykonać wycofanie transakcji dla wszystkich wyjątków (zaznaczone i niezaznaczone), dodając następującą adnotację do usług Grails '@Transactional (rollbackFor = Throwable)' –
Dzięki za napiwek! Nie wiedział tego. – Gregg