In working on a site with the s3fs module, we have encountered various scenarios that cause page loads to fail with the error,
The website encountered an unexpected error. Please try again later. The causes have varied: outbound proxy authentication issues, wrong or missing s3 authentication in the settings.local.php, network failures, etc.. I’m now working on recreating and tracking down some of those issues in the hopes of catching the errors before they cause the page load to fail with an error message in production.
As an example, to simulate an error I truncate the s3fs_file table, clear cache, and remove the settings.local.php file, then try to load the front page, I get the error above. When I look in the error logs, I see:
GuzzleHttpExceptionConnectException: cURL error 35: OpenSSL SSL_connect: SSL_ERROR_SYSCALL in connection to foo.amazonaws.com:443 (see https://curl.haxx.se/libcurl/c/libcurl-errors.html) in GuzzleHttpHandlerCurlFactory::createRejection() (line 202 of /home/appuser/app/vendor/guzzlehttp/guzzle/src/Handler/CurlFactory.php).
I tried adding
debug() before that line. When I then look in the error logs, it turns out to get called a bunch of times before finally failing. For the call just before the site returns the error, it looks like the request to AWS and subsequently Guzzle originates within
… #18 /home/appuser/app/web/modules/contrib/s3fs/src/StreamWrapper/S3fsStream.php(1211): AwsAwsClient->__call('headObject', Array) #19 /home/appuser/app/web/modules/contrib/s3fs/src/StreamWrapper/S3fsStream.php(1071): Drupals3fsStreamWrapperS3fsStream->getS3Metadata('public://styles...') …
It seems the earlier calls generate an
S3Exception error, which
getS3Metadata is set up to catch. The problem is that I’ve tried every variation I can think of or find reference to but I can’t seem to catch
GuzzleHttpExceptionConnectException. I’ve tried switching the catch from
Throwable which continues to catch the the S3Exception but still doesn’t catch the Guzzle’s ConnectException.
First, what am I missing? Second, am I going about this the right way or should I just resign myself to there being unanticipated failure scenarios and use something like the Error custom pages module to present a slightly more pleasant error page to the user?