phplaravelvonageenvoyer.iolaravel-envoyer

Guzzle/Nexmo Issues After Upgrading to Laravel 8


I recently performed a rather large update to this web app, and for the most part it went off without a hitch... Until the app tries to send an SMS notification from staging/production.

The upgrade from laravel 7.x to 8.x was quite simple and straightforward. At the same time we also installed Laravel Horizon. Everything went according to plan, and all works fine locally.

When we deploy to staging/production however, queued SMS notifications fail with the following exception:

ReflectionException: Class Http\Adapter\Guzzle6\Client does not exist in /home/forge/dev.example.com/releases/20210609194554/vendor/laravel/framework/src/Illuminate/Container/Container.php:836

Looking in the stack trace we can see that Nexmo is the culprit:

#5 /home/forge/dev.example.com/releases/20210609194554/vendor/nexmo/laravel/src/NexmoServiceProvider.php(150): Illuminate\Foundation\Application->make()

However in our composer.json file we are requiring Guzzle 7 with the following:

"guzzlehttp/guzzle": "^7.3",

It is worth mentioning again at this point, I have no issues sending SMS locally, the main difference between local and staging environments is that locally I use Laravel Valet and Staging uses Laravel Envoyer.

What I've tried so far:

and more...

Any help is greatly appreciated

UPDATE Below:

Complete composer.json:

{
    "name": "laravel/laravel",
    "description": "The Laravel Framework.",
    "keywords": ["framework", "laravel"],
    "license": "MIT",
    "type": "project",
    "require": {
        "php": ">=7.4.1",
        "arrilot/laravel-widgets": "^3.13",
        "barryvdh/laravel-snappy": "^0.4.6",
        "doctrine/dbal": "^2.10",
        "facade/ignition": "^2.3.6",
        "guzzlehttp/guzzle": "^7.3",
        "intervention/image": "^2.4",
        "laravel/framework": "^8.0",
        "laravel/helpers": "^1.3",
        "laravel/horizon": "^5.7",
        "laravel/nexmo-notification-channel": "^2.5.1",
        "laravel/passport": "^10.0",
        "laravel/slack-notification-channel": "^2.0",
        "laravel/telescope": "^4.0",
        "laravel/tinker": "^2.0",
        "laravel/ui": "^3.0",
        "league/csv": "^8.2",
        "league/flysystem-aws-s3-v3": "~1.0",
        "maatwebsite/excel": "^3.1",
        "milon/barcode": "^8.0.1",
        "nexmo/laravel": "^2.4.1",
        "nunomaduro/collision": "^5.0",
        "predis/predis": "^1.1",
        "pusher/pusher-php-server": "^4.1.1",
        "webpatser/laravel-uuid": "^3.0"
    },
    "require-dev": {
        "fzaninotto/faker": "~1.4",
        "mockery/mockery": "0.9.*",
        "phpunit/phpunit": "^9.0",
        "filp/whoops": "~2.0"
    },
    "autoload": {
        "classmap": [
            "database"
        ],
        "psr-4": {
            "App\\": "app/"
        }
    },
    "autoload-dev": {
        "psr-4": {
            "Tests\\": "tests/"
        }
    },
    "scripts": {
        "post-root-package-install": [
            "php -r \"file_exists('.env') || copy('.env.example', '.env');\""
        ],
        "post-create-project-cmd": [
            "php artisan key:generate"
        ],
        "post-install-cmd": [
            "Illuminate\\Foundation\\ComposerScripts::postInstall"
        ],
        "post-update-cmd": [
            "Illuminate\\Foundation\\ComposerScripts::postUpdate"
        ],
        "post-autoload-dump": [
            "Illuminate\\Foundation\\ComposerScripts::postAutoloadDump",
            "@php artisan package:discover"
        ]
    },
    "config": {
        "preferred-install": "dist",
        "sort-packages": true
    }
}

Additionally my nexmo config file does not have anything for http_client, maybe it's an upgrade step I missed somewhere along the line. As such, I have nothing in my .env file for nexmo's http_client. I will begin looking into this as well.

nexmo.php

<?php

return [

    /*
    |--------------------------------------------------------------------------
    | API Credentials
    |--------------------------------------------------------------------------
    |
    | If you're using API credentials, change these settings. Get your
    | credentials from https://dashboard.nexmo.com | 'Settings'.
    |
    */

    'api_key'    => function_exists('env') ? env('NEXMO_KEY', '') : '',
    'api_secret' => function_exists('env') ? env('NEXMO_SECRET', '') : '',

    /*
    |--------------------------------------------------------------------------
    | Signature Secret
    |--------------------------------------------------------------------------
    |
    | If you're using a signature secret, use this section. This can be used
    | without an `api_secret` for some APIs, as well as with an `api_secret`
    | for all APIs.
    |
    */

    'signature_secret' => function_exists('env') ? env('NEXMO_SIGNATURE_SECRET', '') : '',

    /*
    |--------------------------------------------------------------------------
    | Private Key
    |--------------------------------------------------------------------------
    |
    | Private keys are used to generate JWTs for authentication. Generation is
    | handled by the library. JWTs are required for newer APIs, such as voice
    | and media
    |
    */

    'private_key' => function_exists('env') ? env('NEXMO_PRIVATE_KEY', '') : '',
    'application_id' => function_exists('env') ? env('NEXMO_APPLICATION_ID', '') : '',

    /*
    |----------------------------------------------------------------------------
    | Phone Numbers
    |----------------------------------------------------------------------------
    |
    | Phone numbers to be used by the application.
    */

    'number'    =>  env('NEXMO_NUMBER'),
    'batch'     =>  env('NEXMO_BATCH'),

];

Solution

  • I see that the NexmoServiceProvider is trying to use the defined http_client in the config, so can you share what the .env has for NEXMO_HTTP_CLIENT ? I am pretty sure you have something wrong there or even not defined.

    And this is what it is defined in the config/nexmo.php related to that config:

    'http_client' => function_exists('env') ? env('NEXMO_HTTP_CLIENT', '') : '',