Skip to content

Several operations return non Aws\Result due to name conflicts with Aws\AwsClient methods (similar to #1936) #3194

@sunaoka

Description

@sunaoka

Describe the bug

Some operations on multiple service clients are not returning Aws\Result as expected.
They appear to be shadowed by public methods defined on Aws\AwsClient, same root cause as #1936.

Affected examples I found

  • AppSyncClient::getApi() → returns Aws\Api\Service
  • AmplifyBackendClient::getToken() → returns GuzzleHttp\Promise\Promise
  • IoTDeviceAdvisorClient::getEndpoint() → returns GuzzleHttp\Psr7\Uri
  • IotClient::getCommand() → returns Aws\Command
  • RedshiftServerlessClient::getCredentials() → returns GuzzleHttp\Promise\FulfilledPromise

All of these seem to dispatch Aws\AwsClient methods instead of invoking the service operation and thus do not yield Aws\Result.

Regression Issue

  • Select this option if this issue appears to be a regression.

Expected Behavior

Each call above should invoke the service operation and return an Aws\Result (or a promise of it for *Async variants).

Current Behavior

The calls are resolved to Aws\AwsClient public methods with the same names, returning other types (Aws\Api\Service, GuzzleHttp\Promise\Promise, GuzzleHttp\Psr7\Uri, Aws\Command, GuzzleHttp\Promise\FulfilledPromise).

Reproduction Steps

<?php

use Aws\AmplifyBackend\AmplifyBackendClient;
use Aws\AppSync\AppSyncClient;
use Aws\Iot\IotClient;
use Aws\IoTDeviceAdvisor\IoTDeviceAdvisorClient;
use Aws\RedshiftServerless\RedshiftServerlessClient;

$result = new AppSyncClient([])->getApi();
var_dump(get_class($result));  // Aws\Api\Service

$result = new AmplifyBackendClient([])->getToken();
var_dump(get_class($result));  // GuzzleHttp\Promise\Promise

$result = new IoTDeviceAdvisorClient([])->getEndpoint();
var_dump(get_class($result));  // GuzzleHttp\Psr7\Uri

$result = new IotClient([])->getCommand(['commandId' => '...']);
// **This does not actually work.**
// PHP Fatal error:  Uncaught TypeError: Cannot access offset of type array in isset or empty in ./vendor/aws/aws-sdk-php/src/AwsClient.php:331
// Stack trace:
// #0 ./bug.php(20): Aws\AwsClient->getCommand(Array)
// #1 {main}
//   thrown in ./vendor/aws/aws-sdk-php/src/AwsClient.php on line 33

$result = new IotClient([])->getCommand('getCardinality');
var_dump(get_class($result));  // Aws\Command

$result = new RedshiftServerlessClient([])->getCredentials();
var_dump(get_class($result));  // GuzzleHttp\Promise\FulfilledPromise

Possible Solution

Aws\AwsClient publicly exposes getApi, getCommand, getCredentials, getEndpoint, getToken, etc. (docs show these and their return types). When a service also has operations named GetApi, GetCommand, GetCredentials, GetEndpoint, or GetToken, the client method is picked instead of the dynamic operation method. This matches the historical ApiGatewayV2Client::getApi incident fixed by introducing an operation alias (GetApiResource) in PR #1944. 

Suggested fixes

Apply the same approach as PR #1944: introduce operation aliases for any service whose operation name collides with Aws\AwsClient public methods (e.g., GetApiResource, GetEndpointOperation, etc.). 

Additional Information/Context

References

Thanks for taking a look!

SDK version used

3.356.33

Environment details (Version of PHP (php -v)? OS name and version, etc.)

8.4.13

Metadata

Metadata

Labels

bugThis issue is a bug.needs-triageThis issue or PR still needs to be triaged.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions