[インデックス 12693] ファイルの概要
このコミットは、Go言語のドキュメントツールであるgodoc
コマンドラインツールにおいて、ローカルでgodoc
を実行しているユーザーに対して、Go Playgroundの機能(コードのコンパイルや共有)が利用できないことをより明確に通知するための変更です。具体的には、Go Playgroundのバックエンド機能がローカルのgodoc
サーバーには実装されていないため、ユーザーがこれらの機能を使おうとした際に、一般的なエラーメッセージではなく、より具体的な「この機能はローカルのgodocでは利用できません」というメッセージが表示されるように改善されています。
コミット
commit abdb4dbe2c9c3315f23f68b784fd995e3c5705f7
Author: Andrew Gerrand <adg@golang.org>
Date: Tue Mar 20 14:11:38 2012 +1100
cmd/godoc: inform users that the playground doesn't work via local godoc
R=golang-dev, bradfitz
CC=golang-dev
https://golang.org/cl/5843065
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/abdb4dbe2c9c3315f23f68b784fd995e3c5705f7
元コミット内容
cmd/godoc: inform users that the playground doesn't work via local godoc
R=golang-dev, bradfitz
CC=golang-dev
https://golang.org/cl/5843065
変更の背景
Go言語の公式ウェブサイト(golang.org)には、Go Playgroundと呼ばれるインタラクティブなコード実行環境が組み込まれています。これは、ユーザーがGoのコードをブラウザ上で記述し、コンパイルして実行結果を確認したり、他のユーザーとコードを共有したりできる非常に便利な機能です。
godoc
コマンドは、Goのソースコードからドキュメントを生成し、ローカルでHTTPサーバーとして提供するツールです。これにより、開発者はオフライン環境やプライベートなネットワーク内でGoのドキュメントを閲覧できます。しかし、ローカルで実行されるgodoc
サーバーは、Go Playgroundのコードコンパイルや共有といったバックエンド処理を行う機能を持っていません。これらの機能は、golang.orgのサーバーサイドで提供される特別なサービスに依存しています。
このため、ユーザーがローカルのgodoc
サーバーを通じてGo Playgroundの機能を使おうとすると、バックエンドサービスへの接続エラーが発生していました。以前の実装では、このエラーはJavaScript側で捕捉され、「Error communicating with remote server.」(リモートサーバーとの通信エラー)という一般的なメッセージが表示されるだけでした。このメッセージは、なぜ機能が利用できないのか、その根本的な理由をユーザーに伝えていませんでした。
このコミットの背景には、ユーザーエクスペリエンスの向上という明確な目的があります。ローカルgodoc
の制限をユーザーに明確に伝えることで、混乱を避け、不必要なトラブルシューティングの時間を削減することが意図されています。
前提知識の解説
Go Playground
Go Playgroundは、Go言語のコードをブラウザ上で実行できるウェブサービスです。特徴としては、以下が挙げられます。
- インタラクティブな実行: ユーザーが入力したGoコードをサーバーサイドでコンパイル・実行し、その結果をブラウザに返します。
- 共有機能: コードを永続的なURLとして保存し、他のユーザーと簡単に共有できます。
- サンドボックス環境: セキュリティのために、実行環境は厳しく制限されたサンドボックス内で動作します。ファイルシステムへのアクセスやネットワーク通信は制限されます。
- 特定のGoバージョン: 通常、特定の安定版Goコンパイラが使用されます。
Go Playgroundのバックエンドは、Go言語で書かれた特別なサービスであり、コードのコンパイル、実行、結果のキャッシング、共有URLの生成などを担当しています。
godoc
コマンド
godoc
はGo言語の標準ツールの一つで、Goのソースコードからドキュメントを生成し、ウェブブラウザで閲覧可能な形式で提供します。
- ドキュメント生成: Goのパッケージ、関数、型、変数などのコメントから自動的にドキュメントを生成します。
- ローカルサーバー:
godoc -http=:6060
のように実行することで、指定されたポートでHTTPサーバーを起動し、ローカルマシンからドキュメントを閲覧できるようにします。 - Go Playgroundとの連携: 公式の
godoc
ウェブサイト(golang.org/pkg/など)では、ドキュメント内のコード例にGo Playgroundの機能が組み込まれており、その場でコードを実行・編集できます。
HTTPステータスコード 501 Not Implemented
HTTPステータスコード501 (Not Implemented) は、サーバーがリクエストメソッドを認識しないか、またはそのリクエストを処理する能力がないことを示します。この場合、サーバーはリクエストされた機能を提供できないことをクライアントに明確に伝えます。このコミットでは、ローカルgodoc
サーバーがGo Playgroundのコンパイル・共有機能を提供できないため、このステータスコードが適切に使用されています。
AJAX (Asynchronous JavaScript and XML)
AJAXは、ウェブページ全体をリロードすることなく、サーバーと非同期でデータをやり取りする技術です。Go Playgroundのフロントエンド(JavaScript)は、ユーザーが「Run」ボタンをクリックした際に、AJAXリクエストを使用してGoコードをバックエンドサーバーに送信し、実行結果を受け取ります。エラーが発生した場合、このAJAXリクエストのコールバック関数がエラーを処理します。
技術的詳細
このコミットは、フロントエンド(JavaScript)とバックエンド(Go)の両方に変更を加えて、Go Playgroundの機能がローカルgodoc
で利用できない場合のユーザー通知を改善しています。
バックエンド (src/cmd/godoc/main.go
) の変更
-
新しいハンドラの登録:
http.HandleFunc("/compile", disabledHandler)
http.HandleFunc("/share", disabledHandler)
これらの行が追加され、/compile
と/share
というパスへのHTTPリクエストがdisabledHandler
という新しい関数によって処理されるようになりました。これらはGo Playgroundのコンパイルと共有機能に対応するエンドポイントです。 -
disabledHandler
関数の追加:// disabledHandler serves a 501 "Not Implemented" response. func disabledHandler(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusNotImplemented) fmt.Fprint(w, "This functionality is not available via local godoc.") }
この関数は、HTTPレスポンスのステータスコードを
http.StatusNotImplemented
(501)に設定し、レスポンスボディとして「This functionality is not available via local godoc.」というメッセージを書き込みます。これにより、ローカルgodoc
サーバーは、これらの機能がサポートされていないことを明示的にクライアントに通知します。
フロントエンド (doc/play/playground.js
) の変更
JavaScript側では、AJAXリクエストのエラーハンドリングが強化されています。
-
error
コールバックの改善: 以前は、AJAXリクエストがエラーを返した場合、常にoutput.addClass("error").text("Error communicating with remote server.");
という汎用的なメッセージが表示されていました。 変更後、error
コールバック関数はxhr
オブジェクト(XMLHttpRequestオブジェクト)を受け取るようになり、そのstatus
プロパティをチェックします。error: function(xhr) { var text = "Error communicating with remote server."; console.log(xhr.status); // デバッグ用にステータスをログ出力 if (xhr.status == 501) { text = xhr.responseText; // 501の場合、サーバーからの具体的なメッセージを使用 } output.addClass("error").text(text); }
もし
xhr.status
が501であれば、サーバーから送られてきたxhr.responseText
(この場合は「This functionality is not available via local godoc.」)をエラーメッセージとして表示するように変更されました。これにより、ユーザーはより具体的なエラー情報を得ることができます。 -
complete
コールバックの改善 (共有機能): 共有機能(/share
エンドポイントへのリクエスト)のcomplete
コールバックにも同様のロジックが追加されました。complete: function(xhr) { sharing = false; if (xhr.status == 501) { alert(xhr.responseText); // 501の場合、アラートでサーバーからのメッセージを表示 return; } if (xhr.status != 200) { alert("Server error; try again."); return; } // ... (成功時の処理) }
ここでも、
xhr.status
が501であれば、サーバーからのメッセージをalert
ダイアログで表示し、それ以上の処理を行わないようにしています。これにより、共有機能が利用できない場合もユーザーに明確に通知されます。
これらの変更により、ローカルgodoc
でGo Playgroundの機能を使おうとした際に、サーバーが501エラーを返し、その具体的なメッセージがフロントエンドで表示されるという、よりユーザーフレンドリーな挙動が実現されました。
コアとなるコードの変更箇所
doc/play/playground.js
--- a/doc/play/playground.js
+++ b/doc/play/playground.js
@@ -166,10 +166,13 @@ function playground(opts) {
}
pre.text(out);
},
- error: function() {
- output.addClass("error").text(
- "Error communicating with remote server."
- );
+ error: function(xhr) {
+ var text = "Error communicating with remote server.";
+ console.log(xhr.status);
+ if (xhr.status == 501) {
+ text = xhr.responseText;
+ }
+ output.addClass("error").text(text);
}
});
}
@@ -190,6 +193,10 @@ function playground(opts) {
type: "POST",
complete: function(xhr) {
sharing = false;
+ if (xhr.status == 501) {
+ alert(xhr.responseText);
+ return;
+ }
if (xhr.status != 200) {
alert("Server error; try again.");
return;
src/cmd/godoc/main.go
--- a/src/cmd/godoc/main.go
+++ b/src/cmd/godoc/main.go
@@ -274,6 +274,10 @@ func main() {
registerPublicHandlers(http.DefaultServeMux)
+ // Playground handlers are not available in local godoc.
+ http.HandleFunc("/compile", disabledHandler)
+ http.HandleFunc("/share", disabledHandler)
+
// Initialize default directory tree with corresponding timestamp.
// (Do it in a goroutine so that launch is quick.)
go initFSTree()
@@ -450,3 +454,9 @@ type httpWriter struct {
func (w *httpWriter) Header() http.Header { return w.h }
func (w *httpWriter) WriteHeader(code int) { w.code = code }
+
+// disabledHandler serves a 501 "Not Implemented" response.
+func disabledHandler(w http.ResponseWriter, r *http.Request) {
+ w.WriteHeader(http.StatusNotImplemented)
+ fmt.Fprint(w, "This functionality is not available via local godoc.")
+}
コアとなるコードの解説
src/cmd/godoc/main.go
の変更点
-
http.HandleFunc("/compile", disabledHandler)
とhttp.HandleFunc("/share", disabledHandler)
: Goの標準ライブラリnet/http
パッケージの機能を使用して、特定のURLパス(/compile
と/share
)に対するHTTPリクエストを、disabledHandler
という関数で処理するように登録しています。これにより、これらのパスへのリクエストが来た際に、disabledHandler
が呼び出されます。コメント// Playground handlers are not available in local godoc.
が、この変更の意図を明確に示しています。 -
disabledHandler
関数: この新しい関数は、http.ResponseWriter
と*http.Request
を引数にとる、典型的なHTTPハンドラ関数のシグネチャを持っています。w.WriteHeader(http.StatusNotImplemented)
: HTTPレスポンスのステータスコードを501 (Not Implemented) に設定します。これは、サーバーがリクエストされた機能を提供できないことをクライアントに伝える標準的な方法です。fmt.Fprint(w, "This functionality is not available via local godoc.")
: レスポンスボディに、ユーザー向けの具体的なエラーメッセージを書き込みます。このメッセージは、フロントエンドのJavaScriptによって読み取られ、ユーザーに表示されます。
doc/play/playground.js
の変更点
-
error
コールバックの変更: Go Playgroundのコード実行(/compile
へのAJAXリクエスト)がエラーを返した場合に呼び出されるerror
コールバック関数が修正されました。function(xhr)
: コールバック関数がxhr
オブジェクト(XMLHttpRequestオブジェクト)を受け取るようになりました。このオブジェクトには、HTTPレスポンスのステータスコードやレスポンステキストなどの情報が含まれています。if (xhr.status == 501)
: サーバーから返されたHTTPステータスコードが501であるかをチェックします。text = xhr.responseText;
: もしステータスコードが501であれば、サーバーから送られてきたレスポンスボディ(disabledHandler
が書き込んだメッセージ)をエラーテキストとして使用します。これにより、汎用的なエラーメッセージではなく、サーバーからの具体的なメッセージが表示されるようになります。output.addClass("error").text(text);
: 最終的に、決定されたエラーテキストをHTML要素に表示し、エラーを示すCSSクラスを追加します。
-
complete
コールバックの変更 (共有機能): Go Playgroundのコード共有(/share
へのAJAXリクエスト)が完了した際に呼び出されるcomplete
コールバック関数にも同様のロジックが追加されました。if (xhr.status == 501)
: ここでもステータスコードが501であるかをチェックします。alert(xhr.responseText);
: 501の場合、サーバーからのメッセージをJavaScriptのalert
ダイアログで表示します。これは、ユーザーに即座に通知するための一般的なUIパターンです。return;
:alert
表示後、それ以上の処理を行わずにコールバックを終了します。これにより、共有機能が利用できない場合に不適切な後続処理が実行されるのを防ぎます。
これらの変更は、クライアントとサーバー間の協調によって、より情報豊富でユーザーフレンドリーなエラーハンドリングを実現しています。サーバーは機能が利用できないことを明示的に通知し、クライアントはその通知を解釈してユーザーに分かりやすく表示します。
関連リンク
- Go Playground: https://go.dev/play/
godoc
コマンドのドキュメント: https://pkg.go.dev/cmd/godoc- HTTPステータスコード 501 Not Implemented (MDN Web Docs): https://developer.mozilla.org/ja/docs/Web/HTTP/Status/501
- XMLHttpRequest (MDN Web Docs): https://developer.mozilla.org/ja/docs/Web/API/XMLHttpRequest
参考にした情報源リンク
- Go言語の公式ドキュメント
- MDN Web Docs (Mozilla Developer Network)
- GitHubのコミット履歴と差分表示