開発ブログ

株式会社Nextatのスタッフがお送りする技術コラムメインのブログ。

電話でのお問合わせ 075-744-6842 ([月]-[金] 10:00〜17:00)

  1. top >
  2. 開発ブログ >
  3. PHP >
  4. Laravel >
  5. おかしいぞ!? S3から404が返ってくる。

おかしいぞ!? S3から404が返ってくる。

こんにちは。
ニシザワです。


本日は、Laravelで画像をS3へアップロードまたは削除する際の存在チェックで404になりハマったのでそちらについて書きます。

エラー内容


[object] (GuzzleHttp\\Exception\\ClientException(code: 404): Client error: `GET https://xxxxxx.s3-ap-northeast-1.amazonaws.com/images/hogehoge.jpg` resulted in a `404 Not Found` response:
<?xml version=\"1.0\" encoding=\"UTF-8\"?>
<Error><Code>NoSuchKey</Code><Message>The specified key does not exist.</Message> (truncated...)

S3でファイルが存在しない場合は403が基本的に返されるはずです。
Laravelのファイルシステムのclassを見てみると


    private function checkExistenceWithCommand(CommandInterface $command)
    {
        try {
            $this->execute($command);
            return true;
        } catch (S3Exception $e) {
            if ($e->getAwsErrorCode() == 'AccessDenied') {
                return true;
            }
            if ($e->getStatusCode() >= 500) {
                throw $e;
            }
            return false;
        }
    }

AccessDeniedで判定しています。
今回は存在しない場合404。
おかしいぞ。
公式には404で返すと書いてあるでは有りませんか!!
ということは、Laravelのファイルシステムが悪い?


結論からお伝えすると、なぜ404で帰ってくるのかわからず。。。
Cloud Frontの設定で404を返すようにしていますが、今回Cloud Frontから存在チェックしているわけではないので違う気がします。
取り敢えず解決策


        try {
            Storage::disk('s3')->delete('hoge/fuga.jpg');
        } catch (S3Exception $e) {
            if ($e->getStatusCode() !== 404) {
                throw $e;
            }
        }

        try {
            Storage::disk('s3')->exists('hoge/fuga.jpg');
        } catch (S3Exception $e) {
            if ($e->getStatusCode() !== 404) {
                throw $e;
            }
        }

S3Exceptionを返してくれるので、try catchで捕まえてみました。
こうすることで、404の場合でも次の処理に移すことができる形になります。
ご参考までに。

TOPに戻る