protected < T > T handleRetryExhausted ( RecoveryCallback < T > recoveryCallback , RetryContext context , RetryState state ) throws Throwable { context . setAttribute ( RetryContext . EXHAUSTED , true ) ; if ( state != null && ! context . hasAttribute ( GLOBAL_STATE ) ) { this . retryContextCache . remove ( state . getKey ( ) ) ; } if ( recoveryCallback != null ) { T recovered = recoveryCallback . recover ( context ) ; context . setAttribute ( RetryContext . RECOVERED , true ) ; return recovered ; } if ( state != null ) { this . logger . debug ( "Retry exhausted after last attempt with no recovery path." ) ; rethrow ( context , "Retry exhausted after last attempt with no recovery path" ) ; } throw wrapIfNecessary ( context . getLastThrowable ( ) ) ; }
Actions to take after final attempt has failed . If there is state clean up the cache . If there is a recovery callback execute that and return its result . Otherwise throw an exception .