目的
javascriptのfetchはサーバーのコマンドが失敗しても通信が成功すればerror補足はしないので、自分でなんとかする必要があります。特に子プロセスのエラーメッセージをブラウザに伝える方法についての一考察です。cgiで通信ステータスをなんとかするとかじゃなくて単純にエラーメッセージさえ返せればいいじゃん、ってわけでトライしてみました。ここでのコードは動いたコードを抽象化したので誤記があったらすみません。本格的なエラーハンドリングではないのでしょうが簡単なのでご参考まで。
fetch apiのエラーハンドリングについては例えば↓
処理流れと前提
- 呼び出し経路と処理流れ:ブラウザ(javascript)→通信(apache)→CGI(親プロセス)→子プロセス(エラー)→親プロセス(子プロセスエラー補足とエラーメッセージにhttpのヘッダ付加)→通信→ブラウザ
- モーダル表示はbootbox.jsを使っています(必須ではないです)。見栄えで使っています。 https://bootboxjs.com/
コードの考え方
javascript
javascriptではサーバのエラーメッセージをfetchの.then()
の中でmodalのbootbox()
で表示させます。サーバーからのメッセージの中の"error"を見つけるだけです。alert()
でも問題ないでしょう。
// fetchの基本形(何かを登録した)
fetch("https://yourdomein/cgi/cmd.cgi")
.then((response)=>{
if( ! response.ok ){
bootbox.alert({title: '登録失敗', message: 'レスポンスエラー'});
} else {
response.text().then(text => {
// textの中に"error"文字を捕捉
if (text.includes('error')) {
bootbox.alert({title: '登録失敗 (;´д`)', message: text});
} else {
bootbox.alert({title: '登録成功', message: "登録成功:(⑉•ᴗ•⑉)Thanks❤︎ "});
}
});
}
})
.catch(error => {
bootbox.alert({title: '登録失敗', message: error.message });
});
サーバコマンド(親プロセス:CMD.cgi
)
親プロセスで、子プロセスでエラーの補足とエラーメッセージを受け取り通信に返します。
#!/usr/bin/env bash
set -vxeu
# エラーメッセージを出力して終了 文字列にはerrorを入れること
error500(){
echo "Content-type: text/html"
echo ""
echo "$@"
exit 1
}
# 子プロセスの起動とエラー補足
if ! errmsg=$( child.bash 2>&1 ); then
error500 "error in child.bash: $errmsg"
fi
子プロセス(child.bash
)
子プロセスでは普通にエラーメッセージで終了します。
#!/usr/bin/env bash
# エラーのみ出す cgiから呼ばれるbashはこれを使うこと
error(){
echo "$@"
exit 1
}
# commandが失敗した場合、errorを実行します。
command || error "command error because ..."
適用したコードのブラウザ画面例
まとめ
サーバーの子プロセスのエラーメッセージをどうしたらfetch()
に返せるかいろいろ調べたのですが長年わからなかった。今日久しぶりに生成AIと一緒に取り組んだら見つけられたので共有です。誰かのお役に立てれば幸いです。