55namespace FlixTech \SchemaRegistryApi \Exception ;
66
77use Exception ;
8- use GuzzleHttp \Exception \RequestException ;
98use Psr \Http \Message \ResponseInterface ;
10- use RuntimeException ;
119use function array_key_exists ;
10+ use function FlixTech \SchemaRegistryApi \Requests \jsonDecode ;
1211use function sprintf ;
1312
1413final class ExceptionMap
@@ -31,38 +30,56 @@ public static function instance(): ExceptionMap
3130 return self ::$ instance ;
3231 }
3332
33+ /**
34+ * @var array<int, callable>
35+ */
36+ private $ map ;
37+
3438 private function __construct ()
3539 {
40+ $ factoryFn = static function (string $ exceptionClass ): callable {
41+ return static function (int $ errorCode , string $ errorMessage ) use ($ exceptionClass ): SchemaRegistryException {
42+ return new $ exceptionClass ($ errorMessage , $ errorCode );
43+ };
44+ };
45+
46+ $ this ->map = [
47+ IncompatibleAvroSchemaException::errorCode () => $ factoryFn (IncompatibleAvroSchemaException::class),
48+ BackendDataStoreException::errorCode () => $ factoryFn (BackendDataStoreException::class),
49+ OperationTimedOutException::errorCode () => $ factoryFn (OperationTimedOutException::class),
50+ MasterProxyException::errorCode () => $ factoryFn (MasterProxyException::class),
51+ InvalidVersionException::errorCode () => $ factoryFn (InvalidVersionException::class),
52+ InvalidAvroSchemaException::errorCode () => $ factoryFn (InvalidAvroSchemaException::class),
53+ SchemaNotFoundException::errorCode () => $ factoryFn (SchemaNotFoundException::class),
54+ SubjectNotFoundException::errorCode () => $ factoryFn (SubjectNotFoundException::class),
55+ VersionNotFoundException::errorCode () => $ factoryFn (VersionNotFoundException::class),
56+ InvalidCompatibilityLevelException::errorCode () => $ factoryFn (InvalidCompatibilityLevelException::class),
57+ ];
3658 }
3759
3860 /**
39- * Maps a RequestException to the internal SchemaRegistryException types.
61+ * Maps a ResponseInterface to the internal SchemaRegistryException types.
4062 *
41- * @param RequestException $exception
63+ * @param ResponseInterface $response
4264 *
4365 * @return SchemaRegistryException
4466 *
4567 * @throws RuntimeException
4668 */
47- public function __invoke ( RequestException $ exception ): SchemaRegistryException
69+ public function exceptionFor ( ResponseInterface $ response ): SchemaRegistryException
4870 {
49- $ response = $ this ->guardAgainstMissingResponse ($ exception );
5071 $ decodedBody = $ this ->guardAgainstMissingErrorCode ($ response );
5172 $ errorCode = $ decodedBody [self ::ERROR_CODE_FIELD_NAME ];
52- $ errorMessage = $ decodedBody [self ::ERROR_MESSAGE_FIELD_NAME ];
73+ $ errorMessage = $ decodedBody [self ::ERROR_MESSAGE_FIELD_NAME ] ?? " Unknown Error " ;
5374
5475 return $ this ->mapErrorCodeToException ($ errorCode , $ errorMessage );
5576 }
5677
57- private function guardAgainstMissingResponse ( RequestException $ exception ): ResponseInterface
78+ public function hasMappableError ( ResponseInterface $ response ): bool
5879 {
59- $ response = $ exception -> getResponse ();
80+ $ statusCode = $ response -> getStatusCode ();
6081
61- if (!$ response ) {
62- throw new RuntimeException ('RequestException has no response to inspect ' , 0 , $ exception );
63- }
64-
65- return $ response ;
82+ return $ statusCode >= 400 && $ statusCode < 600 ;
6683 }
6784
6885 /**
@@ -72,7 +89,7 @@ private function guardAgainstMissingResponse(RequestException $exception): Respo
7289 private function guardAgainstMissingErrorCode (ResponseInterface $ response ): array
7390 {
7491 try {
75- $ decodedBody = \ GuzzleHttp \json_decode ((string ) $ response ->getBody (), true );
92+ $ decodedBody = jsonDecode ((string ) $ response ->getBody ());
7693
7794 if (!array_key_exists (self ::ERROR_CODE_FIELD_NAME , $ decodedBody )) {
7895 throw new RuntimeException (
@@ -98,39 +115,10 @@ private function guardAgainstMissingErrorCode(ResponseInterface $response): arra
98115
99116 private function mapErrorCodeToException (int $ errorCode , string $ errorMessage ): SchemaRegistryException
100117 {
101- switch ($ errorCode ) {
102- case IncompatibleAvroSchemaException::errorCode ():
103- return new IncompatibleAvroSchemaException ($ errorMessage , $ errorCode );
104-
105- case BackendDataStoreException::errorCode ():
106- return new BackendDataStoreException ($ errorMessage , $ errorCode );
107-
108- case OperationTimedOutException::errorCode ():
109- return new OperationTimedOutException ($ errorMessage , $ errorCode );
110-
111- case MasterProxyException::errorCode ():
112- return new MasterProxyException ($ errorMessage , $ errorCode );
113-
114- case InvalidVersionException::errorCode ():
115- return new InvalidVersionException ($ errorMessage , $ errorCode );
116-
117- case InvalidAvroSchemaException::errorCode ():
118- return new InvalidAvroSchemaException ($ errorMessage , $ errorCode );
119-
120- case SchemaNotFoundException::errorCode ():
121- return new SchemaNotFoundException ($ errorMessage , $ errorCode );
122-
123- case SubjectNotFoundException::errorCode ():
124- return new SubjectNotFoundException ($ errorMessage , $ errorCode );
125-
126- case VersionNotFoundException::errorCode ():
127- return new VersionNotFoundException ($ errorMessage , $ errorCode );
128-
129- case InvalidCompatibilityLevelException::errorCode ():
130- return new InvalidCompatibilityLevelException ($ errorMessage , $ errorCode );
131-
132- default :
133- throw new RuntimeException (sprintf ('Unknown error code "%d" ' , $ errorCode ));
118+ if (!array_key_exists ($ errorCode , $ this ->map )) {
119+ throw new RuntimeException (sprintf ('Unknown error code "%d" ' , $ errorCode ));
134120 }
121+
122+ return $ this ->map [$ errorCode ]($ errorCode , $ errorMessage );
135123 }
136124}
0 commit comments