在调用 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 namespace 和S3Exception class。 EC2 有Aws\Ec2\Exception namespace 和Ec2Exception 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 操作的页面包含一个“错误”部分,列出了它可以返回的错误代码。