调用 AWS 开发工具包的方法时发生的所有错误都通过引发异常来指示。如果要处理错误,可以捕获这些异常。
在最简单的情况下,您可能只想捕获Exception
:
try {
$result = $s3->getObject(array(
'Bucket' => 'my bucket',
'Key' => 'path/to/file'
));
}
catch (Exception $e) {
echo 'Oops, something went wrong';
}
但是,如果您只想处理某些预期的异常,同时让其他人冒泡并让您的应用程序崩溃,那么事情就会变得更加微妙。
首先, AWS 命名空间中的几十个命名空间中的每一个都包含一个Exception
命名空间,其中定义了异常类。每个命名空间中的这些类之一是 Amazon 称之为命名空间的默认服务异常类,所有其他异常都从该类继承。
例如,S3 有Aws\S3\Exception
命名空间和S3Exception
类。EC2 具有Aws\Ec2\Exception
命名空间和Ec2Exception
类。
请注意,捕获这些异常之一而不是基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
.
让我们回到如何处理特定错误的问题。对于大多数命名空间,答案是将为该错误定义一个异常类,您应该抓住它。例如,假设我们再次使用 S3getObject
方法,并且想要在我们请求的存储桶不存在时做一些事情。查看S3 Exception 命名空间文档,我们看到有一个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()
异常方法返回的值来做到这一点。
例如,我最近编写的脚本中的(修改的)片段授予指定 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 SDK 文档中未列出可能的异常代码(如本例所示),但您可以通过反复试验或从EC2 API 本身的文档中找到它们,其中每个 API 操作的页面都包含一个“错误部分列出了它可以返回的错误代码。