Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/amazon-s3/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Amazon web services AWS PHP SDK 2中的错误处理_Amazon Web Services_Amazon S3 - Fatal编程技术网

Amazon web services AWS PHP SDK 2中的错误处理

Amazon web services AWS PHP SDK 2中的错误处理,amazon-web-services,amazon-s3,Amazon Web Services,Amazon S3,如果我试图从我的S3存储桶中获取一个不存在的对象,AmazonPHPSDK2会给我一个非常糟糕的错误。对我来说很方便,但对最终用户来说毫无意义 例如: 错误: 致命错误:未捕获Aws\S3\Exception\NoSuchKeyException:Aws错误代码:NoSuchKey,状态代码:404,Aws请求ID:xxxxxxxx,Aws错误类型:客户端,Aws错误消息:指定的密钥不存在。在第89行的AWS/vendor/AWS/AWS sdk php/src/AWS/Common/Excep

如果我试图从我的S3存储桶中获取一个不存在的对象,AmazonPHPSDK2会给我一个非常糟糕的错误。对我来说很方便,但对最终用户来说毫无意义

例如:

错误:

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


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

我突然想到尝试以下方法:

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

调用AWS SDK的方法时发生的所有错误都通过抛出异常来表示。如果要处理错误,可以捕获这些异常

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

try {
    $result = $s3->getObject(array(
        'Bucket' => 'my bucket',
        'Key'    => 'path/to/file'
    ));
}
catch (Exception $e) {
    echo 'Oops, something went wrong';
}
但是,如果您只想处理某些预期的异常,而让其他异常冒泡并使您的应用程序崩溃,那么事情就会变得更加微妙

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

例如,S3具有和。EC2具有和

请注意,捕获这些异常中的一个而不是基本的
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),程序将崩溃。因此,如果捕获这些异常只是为了向用户提供一般故障消息,那么您可能应该捕获
异常

让我们回到如何处理特定错误的问题。对于大多数名称空间,答案是将为该错误定义一个异常类,您应该捕获该异常类。例如,假设我们再次使用S3
getObject
方法,并希望在我们请求的bucket不存在时执行某些操作。从地图上看,我们可以发现:

try {
    $result = $s3->getObject(array(
        'Bucket' => 'my bucket',
        'Key'    => 'path/to/file'
    ));
}
catch (NoSuchBucketException $e) {
    echo 'There is no such bucket.';
}
(在实践中,通过试错比仔细阅读文档更容易找出哪些操作可能引发哪些异常。)

最后,值得一提的是EC2API。与所有其他服务不同,EC2命名空间只包含一个异常类,即。如果希望捕获并处理特定错误,则需要检查异常对象,以确定正在处理的错误类型。您可以通过检查异常方法返回的值来实现这一点

例如,我最近编写的一个脚本中的一个(修改过的)片段,该脚本授予对MySQL服务器的指定IP访问权:

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;
    }
}

请注意,AWS PHP SDK文档中未列出可能的异常代码(如本例中的
InvalidPermission.Duplicate
),但您可以通过反复试验或从,其中每个API操作的页面都包含一个“错误”部分,列出它可以返回的错误代码。

您也可以使用此方法:
$response=$s3->doesObjectExist($bucket,$key)

如果对象存在,它将返回布尔真响应


如果您在S3上启用网页,您可以选择将“未找到文件”错误重定向到页面(在我的情况下,我使用的jpg文件显示“未找到文件”,因此这也适用于图像)。谢谢@Alvin K。我不确定这对我有多个文件类型,因此返回jpg文件对我没有帮助。不过还是要谢谢你。由于jpg文件是固定的,md5校验和将标识返回的文件,你将“捕获”这个404错误。只有当getObject()未连接时才会发生异常,通常它将返回一个对象,无论它是带错误代码的XML还是FileNotFound.jpg或你正在查找的实际文件。谢谢Alvin,到目前为止还没有返回任何对象,只是一个错误。也许你有不同的配置。我相信,如果对象不存在,您可以将其设置为返回对象(如404图像)。@AlvinK。你错了;AWS的PHP SDK在收到服务器的错误响应时会自动抛出异常——不仅仅是因为连接失败。我们很幸运,PHP AWS SDK的源代码在github中,我查了一下,了解到这个API是Michael Dowling在2012年7月12日添加的。因此,是的,它是相对较新的,它可能在一段时间后作为更新版本的一部分推出。我喜欢亚马逊让AWS变得更好的方式!不幸的是,它不在AmazonS3v3中
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;
    }
}