private function fetchSchemaAt($uri)
    {
        if ($hook = $this->preFetchHook) {
            $uri = $hook($uri);
        }

        set_error_handler(function ($severity, $error) use ($uri) {
            restore_error_handler();
            throw new UnfetchableUriException([$uri, $error, $severity]);
        });

        $content = file_get_contents($uri);
        restore_error_handler();

        $schema = json_decode($content);

        if (json_last_error() !== JSON_ERROR_NONE) {
            throw new JsonDecodeException(sprintf(
                'Cannot decode JSON from URI "%s" (error: %s)',
                $uri,
                Utils::lastJsonErrorMessage()
            ));
        }

        if (!is_object($schema)) {
            throw new InvalidRemoteSchemaException([$uri]);
        }

        return $schema;
    }