LoginSignup
4
0

More than 3 years have passed since last update.

Cloud Internet ServicesのEdge FunctionとCloud Object Storageでアプリケーションエラー時にSorryページを返す

Last updated at Posted at 2020-05-08

目的

Cloud Internet Services(以下、CIS)はCloudflare社のサービスをIBM Cloud向けに提供しているものです。CISではGLBを定義してバックエンドのアプリケーションへのプロクシアクセスを実現しますが、もし、アプリケーションとの接続エラーが発生した場合、CISデフォルトのエラーページがクライアントに返ります。以下例です。

image.png

これですとあまりユーザーフレンドリーとは言えませんので、CISではカスタムページを使って、独自のコンテンツに置き換えることができます。

https://cloud.ibm.com/docs/infrastructure/cis?topic=cis-custom-page&locale=ja

しかし、上記ドキュメントに記載されていますが、

応答 500、501、503、および 505 は、特定の API エンドポイントおよび他の Web アプリケーションの中断を回避するために、カスタム・エラー・ページをトリガーしません。

となっており、肝心の一番出やすいアプリケーションのエラーに対しては、CISデフォルトのエラーページやカスタムページを使うことができません。この場合は、アプリケーションのエラー画面がそのままクライアントに返るようです。

そのとき、もしアプリケーションのエラー画面をユーザーフレンドリーにしたい場合はアプリケーション側で対応しなければいけませんが、アプリケーションの制約でエラー画面をカスタマイズできなかったり、できたとしても面倒なケースがあります。

そこで、今回はCISのEdge FunctionとCloud Object Storage(以下、COS)を使って簡単にSorryページを作ってみます。

前提

  • Edge Functionを使うためにはCISのEnterprise以上のプランが必要です
  • アプリケーションはすでにCISのGLB配下に設定されているものとします

手順

COSをオーダーする(略)

バケットを作成する(略)

バケットをパブリックアクセスにする

image.png

Sorryページのコンテンツをバケットに置く

sorry.html
<!DOCTYPE html>
<html>
  <head>
    <meta http-equiv="Content-type" content="text/html; charset=utf-8">
    <title>Sorry</title>
  </head>
  <body>
    ごめん
  </body>
</html>

image.png

CISでEdge Functionのアクションを登録する

const sorryUrl = "https://${バケット名}.s3.jp-tok.cloud-object-storage.appdomain.cloud/sorry.html";

addEventListener('fetch', event => {
    event.respondWith(handleRequest(event.request))
})

async function handleRequest(request) {
    let originalResponse = await fetch(request);
    if (originalResponse.status >= 500) {
        let sorryResponse = await fetch(sorryUrl);
        return new Response(await sorryResponse.text(), {
            status: originalResponse.status,
            statusText: originalResponse.statusText,
            headers: {
                "Content-Type": "text/html; charset=utf-8"
            }
        });
    } else {
        return originalResponse;
    }
}

image.png

アクションをトリガーで紐づける

image.png

テスト

アプリケーションで503エラーが出る状態にしておいて、

$ curl https://****************/****/ -v
(略)
> GET /****/ HTTP/1.1
> User-Agent: curl/7.29.0
> Host: ****************
> Accept: */*
>
< HTTP/1.1 503 Service Unavailable
< Date: Fri, 08 May 2020 19:51:01 GMT
< Content-Type: text/html; charset=utf-8
(略)
<
<!DOCTYPE html>
<html>
  <head>
    <meta http-equiv="Content-type" content="text/html; charset=utf-8">
    <title>Sorry</title>
  </head>
  <body>
    ごめん
  </body>
</html>

image.png

うまくいきました。

補足

当初はEdge Functionでコンテンツをフェッチするのではなく、単にバケットへのRedirectをしようとしていましたが、その場合、最終的なステータスコードが200になってしまうのと、レスポンスのContent-Typeがapplication/octet-streamになってしまうのでやめました。

4
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
0