Lullabot/mpx-php

View on GitHub
src/Middleware.php

Summary

Maintainability
A
0 mins
Test Coverage
A
100%
<?php

namespace Lullabot\Mpx;

use Lullabot\Mpx\Exception\MpxExceptionFactory;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface;

/**
 * Guzzle middleware functions.
 */
class Middleware
{
    /**
     * A middleware to check for MPX errors in the body of the response.
     *
     * @see https://docs.theplatform.com/help/wsf-handling-data-service-exceptions
     *
     * @return \Closure A middleware function.
     */
    public static function mpxErrors(): \Closure
    {
        // Guzzle's built-in middlewares also have this level of nested
        // functions, so we follow the same pattern even though it's difficult
        // to read.
        return fn (callable $handler) => fn (RequestInterface $request, array $options) => // We only need to process after the request has been sent.
$handler($request, $options)->then(
    function (ResponseInterface $response) use ($request) {
        // While it's not documented, we want to be sure that
        // any 4XX or 5XX errors that break through suppression
        // are still parsed. In other words, this handler should
        // be executed before the normal Guzzle error handler.

        // If our response isn't JSON, we can't parse it.
        $contentType = $response->getHeaderLine('Content-Type');
        if (0 === preg_match('!^(application|text)\/json!', $contentType)) {
            return $response;
        }

        $data = \GuzzleHttp\Utils::jsonDecode($response->getBody(), true);

        // Notification responses have a different exception format.
        if (isset($data[0]) && isset($data[0]['type']) && 'Exception' == $data[0]['type']) {
            throw MpxExceptionFactory::createFromNotificationException($request, $response);
        }

        if (empty($data['responseCode']) && empty($data['isException'])) {
            return $response;
        }

        throw MpxExceptionFactory::create($request, $response);
    }
);
    }
}