【问题标题】:Handling errors in AWS PHP SDK 2处理 AWS PHP SDK 2 中的错误
【发布时间】:2013-04-10 06:42:22
【问题描述】:

如果我尝试从我的 S3 存储桶中获取一个不存在的对象,Amazon PHP SDK 2 会给我一个非常难看的错误。对我来说很方便,但对最终用户毫无意义......

例如:

$s3 = $aws->get('s3');

$result = $s3->getObject(array(
    'Bucket' => 'my bucket',
    'Key'    => 'path/to/file'
));

错误:

致命错误:未捕获的 Aws\S3\Exception\NoSuchKeyException:AWS 错误代码:NoSuchKey,状态代码:404,AWS 请求 ID:xxxxxxxxxxxxx,AWS 错误类型:客户端,AWS 错误消息:指定的密钥不存在。在第 89 行的 AWS/vendor/aws/aws-sdk-php/src/Aws/Common/Exception/NamespaceExceptionFactory.php 中抛出

有没有一种方法可以确定是否存在错误并打印出有意义的消息而不是上述消息?

【问题讨论】:

  • 如果您在 S3 上启用网页,您可以选择将 File Not Found 错误重定向到页面(在我的情况下,我使用显示“File Not Found”的 jpg 文件,所以这也适用于图像)
  • 谢谢@Alvin K。由于我有多种文件类型,所以不知道这对我有什么用,所以返回一个 JPG 文件并不能真正帮助我。不过还是谢谢。
  • 由于 jpg 文件已修复,md5 校验和将识别返回哪个文件,然后您“捕获”此 404 错误。

标签: amazon-web-services amazon-s3


【解决方案1】:

我突然想到要试试这个:

try {
    $result = $s3->getObject(array(
        'Bucket' => 'my bucket',
        'Key'    => 'path/to/file'
    ));
} catch (Exception $e) {
   // I can put a nicer error message here  
}

【讨论】:

  • 只有在 getObject() 没有连接时才会发生异常,通常它会返回一个对象,无论是带有错误代码的 XML 还是 FileNotFound.jpg 或您正在寻找的实际文件。
  • 感谢 Alvin,到目前为止还没有返回任何对象,只是一个错误。也许你有不同的配置。如果对象不存在,我相信您可以将其设置为返回对象(如 404 图像)。
  • @AlvinK。你错了; AWS 的 PHP 开发工具包在接收到来自服务器的错误响应时自动抛出异常 - 仅针对连接失败。
【解决方案2】:

在调用 AWS 开发工具包的方法中发生的所有错误都通过引发异常来指示。如果您想处理错误,可以捕获这些异常。

在最简单的情况下,您可能只想捕获Exception

try {
    $result = $s3->getObject(array(
        'Bucket' => 'my bucket',
        'Key'    => 'path/to/file'
    ));
}
catch (Exception $e) {
    echo 'Oops, something went wrong';
}

但是,如果您只想处理某些预期的异常,同时让其他异常冒泡并使您的应用程序崩溃,那么事情就会变得更加微妙。

首先,AWS namespace 中的几十个命名空间中的每一个都包含一个 Exception 命名空间,其中定义了异常类。每个命名空间中的其中一个类是 Amazon 为命名空间调用的默认服务异常类,所有其他异常都从该类继承。

例如,S3 有Aws\S3\Exception namespaceS3Exception class。 EC2 有Aws\Ec2\Exception namespaceEc2Exception class

请注意,捕获这些异常之一而不是基类 Exception 会立即阻止我们捕获某些错误!服务器的错误响应会引发特定于服务的异常;连接失败异常从它们继承。例如,如果您尝试在没有 Internet 连接的情况下运行以下代码...

try {
    $result = $s3->getObject(array(
        'Bucket' => 'my bucket',
        'Key'    => 'path/to/file'
    ));
}
catch (S3Exception $e) {
    echo 'Oops, something went wrong';
}

... 那么异常将不会被捕获(因为它将是Guzzle\Http\Exception\CurlException,而不是 S3Exception)并且程序将崩溃。出于这个原因,如果您捕获这些异常只是为了向用户提供一般的失败消息,您可能应该捕获Exception

让我们回到如何处理特定错误的问题。对于大多数命名空间,答案是将为该错误定义一个异常类,您应该抓住它。例如,假设我们再次使用 S3 getObject 方法,并且想要在我们请求的存储桶不存在时做一些事情。查看S3 Exception namespace docs,我们看到有一个NoSuchBucketException我们可以捕捉到:

try {
    $result = $s3->getObject(array(
        'Bucket' => 'my bucket',
        'Key'    => 'path/to/file'
    ));
}
catch (NoSuchBucketException $e) {
    echo 'There is no such bucket.';
}

(在实践中,通过反复试验比仔细阅读文档更容易确定哪些操作会引发哪些异常。)

最后,值得一提的是 EC2 API。与所有其他服务不同,EC2 命名空间仅包含一个异常类,Ec2Exception。如果您想捕获并处理特定错误,则需要检查异常对象以找出您正在处理的错误类型。您可以通过检查异常的getExceptionCode() 方法返回的值来做到这一点。

例如,我最近编写的脚本中的(修改后的)sn-p 授予指定 IP 访问我们的 MySQL 服务器的权限:

try {
    $result = $ec2->authorizeSecurityGroupIngress([
        'GroupName' => 'mygroup',
        'IpProtocol' => 'tcp',
        'ToPort' => 3306,
        'CidrIp' => $ip . "/32",
    ]);
}
catch (Ec2Exception $e) {
    if ($e->getExceptionCode() == 'InvalidPermission.Duplicate') {
        echo "IP already has requested permission.";
    }
    else {
        // Don't know how to deal with this error; let's crash
        throw $e;
    }
}

请注意,可能的异常代码(如本例中的 InvalidPermission.Duplicate)未在 AWS PHP 开发工具包文档中列出,但您可以通过反复试验或从 documentation for the EC2 API itself 找到它们,其中每个 API 操作的页面包含一个“错误”部分,列出了它可以返回的错误代码。

【讨论】:

    【解决方案3】:

    你也可以使用这个方法: $response = $s3->doesObjectExist( $bucket, $key );

    如果对象存在,它将返回一个布尔值 true 响应。

    AWS Docs for doesObjectExist

    【讨论】:

    • 我们很幸运,PHP aws sdk 的源代码在 github 中,我查了一下,得知这个 API 是 Michael Dowling 在 2012 年 7 月 12 日添加的。所以是的,它相对较新,它可能已在一段时间后作为更新版本的一部分推出。我喜欢亚马逊如何不断让 AWS 变得更好! github.com/aws/aws-sdk-php/blame/master/src/Aws/S3/S3Client.php
    • 遗憾的是它不在 amazon s3 v3 中
    猜你喜欢
    • 1970-01-01
    • 2012-11-10
    • 2018-09-21
    • 1970-01-01
    • 1970-01-01
    • 2016-01-06
    • 1970-01-01
    • 2010-12-14
    • 2015-07-05
    相关资源
    最近更新 更多