77use ScriptFUSION \Porter \Cache \CacheUnavailableException ;
88use ScriptFUSION \Porter \Connector \Recoverable \RecoverableExceptionHandler ;
99use ScriptFUSION \Porter \Connector \Recoverable \StatelessRecoverableExceptionHandler ;
10+ use ScriptFUSION \Porter \ExceptionDescriptor ;
1011
1112/**
1213 * Connector whose lifecycle is synchronised with an import operation. Ensures correct ConnectionContext is delivered
@@ -27,21 +28,26 @@ final class ImportConnector implements ConnectorWrapper
2728 *
2829 * @var RecoverableExceptionHandler
2930 */
30- private $ userReh ;
31+ private $ userExceptionHandler ;
3132
3233 /**
3334 * Resource-defined exception handler called when a recoverable exception is thrown by Connector::fetch().
3435 *
3536 * @var RecoverableExceptionHandler
3637 */
37- private $ resourceReh ;
38+ private $ resourceExceptionHandler ;
3839
3940 private $ maxFetchAttempts ;
4041
42+ /**
43+ * @var ExceptionDescriptor[]
44+ */
45+ private $ recoverableExceptionDescriptors = [];
46+
4147 /**
4248 * @param Connector|AsyncConnector $connector Wrapped connector.
4349 * @param ConnectionContext $connectionContext Connection context.
44- * @param RecoverableExceptionHandler $recoverableExceptionHandler
50+ * @param RecoverableExceptionHandler $recoverableExceptionHandler User's recoverable exception handler.
4551 * @param int $maxFetchAttempts
4652 */
4753 public function __construct (
@@ -56,7 +62,7 @@ public function __construct(
5662
5763 $ this ->connector = clone $ connector ;
5864 $ this ->connectionContext = $ connectionContext ;
59- $ this ->userReh = $ recoverableExceptionHandler ;
65+ $ this ->userExceptionHandler = $ recoverableExceptionHandler ;
6066 $ this ->maxFetchAttempts = $ maxFetchAttempts ;
6167 }
6268
@@ -92,20 +98,35 @@ private function createExceptionHandler(): \Closure
9298
9399 return function (\Exception $ exception ) use (&$ userHandlerCloned , &$ resourceHandlerCloned ): void {
94100 // Throw exception instead of retrying, if unrecoverable.
95- if (!$ exception instanceof RecoverableConnectorException ) {
101+ if (!$ this -> isRecoverable ( $ exception) ) {
96102 throw $ exception ;
97103 }
98104
99105 // Call resource's exception handler, if defined.
100- if ($ this ->resourceReh ) {
101- self ::invokeHandler ($ this ->resourceReh , $ exception , $ resourceHandlerCloned );
106+ if ($ this ->resourceExceptionHandler ) {
107+ self ::invokeHandler ($ this ->resourceExceptionHandler , $ exception , $ resourceHandlerCloned );
102108 }
103109
104110 // Call user's exception handler.
105- self ::invokeHandler ($ this ->userReh , $ exception , $ userHandlerCloned );
111+ self ::invokeHandler ($ this ->userExceptionHandler , $ exception , $ userHandlerCloned );
106112 };
107113 }
108114
115+ private function isRecoverable (\Exception $ exception ): bool
116+ {
117+ if ($ exception instanceof RecoverableConnectorException) {
118+ return true ;
119+ }
120+
121+ foreach ($ this ->recoverableExceptionDescriptors as $ exceptionDescriptor ) {
122+ if ($ exceptionDescriptor ->matches ($ exception )) {
123+ return true ;
124+ }
125+ }
126+
127+ return false ;
128+ }
129+
109130 /**
110131 * Invokes the specified fetch exception handler, cloning it if required.
111132 *
@@ -163,10 +184,20 @@ public function findBaseConnector()
163184 */
164185 public function setRecoverableExceptionHandler (RecoverableExceptionHandler $ recoverableExceptionHandler ): void
165186 {
166- if ($ this ->resourceReh !== null ) {
187+ if ($ this ->resourceExceptionHandler !== null ) {
167188 throw new \LogicException ('Cannot set resource \'s recoverable exception handler: already set! ' );
168189 }
169190
170- $ this ->resourceReh = $ recoverableExceptionHandler ;
191+ $ this ->resourceExceptionHandler = $ recoverableExceptionHandler ;
192+ }
193+
194+ /**
195+ * Adds the specified exception descriptor, designating it as a recoverable exception type.
196+ *
197+ * @param ExceptionDescriptor $descriptor
198+ */
199+ public function addRecoverableExceptionDescriptor (ExceptionDescriptor $ descriptor ): void
200+ {
201+ $ this ->recoverableExceptionDescriptors [] = $ descriptor ;
171202 }
172203}
0 commit comments