デバッグ・トラブルシューティング

CHIRIMEN Raspi3 を利用する上で基礎的なデバッグやトラブルシューティングを共有するページです。良くある質問については FAQ ページ に、利用上のテクニックや知っておくと良いことは TIPS ページ に書いているので、そちらも合わせてご覧ください。

はじめに

CHIRIMEN Raspi3 でのプログラミングでも Web アプリケーションのプログラミングでも問題解決の手順は共通です。プログラムは意図したとおりではなく書いた通りに動くので、実際のコードや配線が意図通りか、一つずつ検証し、問題の原因となる範囲を絞っていくことが大事です。

まずは開発ツールのconsoleを開きましょう(CTRL+SHIFT+I) エラーメッセージなどがここに出力されます。また更新した内容が即座に反映するようにCacheをDisableにしておきましょう(開発ツールのSettings/Preferencesから指定できます)

プログラム中にconsole.log関数 console.log(カンマ区切りで確認したい変数などを記載); を書けば、先のconsole上に確認したい値が出力されます。これも基本的なデバッグのテクニックです。詳しくは下記開発ツール (DevTools) のリンクなどを参考にしてください。

エラーメッセージやデバイスの LED 表示、あるいは焦げた匂いなど問題のヒントがある時はまずそこから確認し、そのエラーメッセージが発生する原因を探ります。JavaScript では console.log で変数の状態を書き出しながら実行するだけでなく、開発ツール (DevTools) を使ってデバッグ することが解決の早道です。ブレークポイント でコードの実効を一時停止し、そのコードが意図通りのタイミング、回数、変数の状態で呼ばれているか確認するようにすると素早くデバッグできるようになります。

講師やチューターのいる場面ではデバッグの仕方も積極的に教えてもらってください。

デバッグチェックリスト

問題解決のためのチェックリスト (初心者向け) を書いてみたので参考にしてください:

トラブルシューティング

ディスプレイに何も表示されない

Raspi に AC アダプタと microUSB ケーブルを接続して (ケーブルにスイッチがあればオンにして) も HDMI ディスプレイに何も表示されない場合にはいくつかの原因が考えられます。

ssh や VNC で接続できない

pi ユーザのパスワードが分からない

本ページ執筆時点で CHIRIMEN の配付イメージは Raspbian をベースにしていますが pi ユーザのパスワードは Raspbian デフォルトの raspberry ではなく rasp に変更されています。

なお、パスワード設定変更はイメージ作成スクリプト setup.sh で行われています。

同時に複数のタブで開くと動作しない

制限事項です。API では特に規定されていませんが排他制御をしており同一のページを複数タブで開くなど、同じポートを同時に扱うコードを書くと正しく動作しなくなることがあります。全てのタブを閉じてから目的のページだけを開き直してください。

コンソールに Uncaught ReferenceError: xxx is not defined などと表示される

変数 xxx にアクセスしようとしているがそれが定義されていないというエラーです。単純に変数名などを Typo (入力し間違え) していることが多いです。次に多いのは定義域の外でアクセスしようとしている場合です。JavaScript の変数スコープは var で宣言した場合は関数単位、let や const で宣言した場合にはブロック単位です。別の関数の中からなど、スコープ外からアクセスしようとしていないか確認してください。

コンソールに Uncaught TypeError: Cannot read property 'xxx' of nullUncaught TypeError: Cannot read property 'xxx' of undefined などと表示される

オブジェクトのプロパティ xxx にアクセスしようとしている (some.xxx のようなコード)、プロパティ xxx を持つと考えている変数 some がオブジェクトではなく null や undefined となっており、プロパティアクセスができないというエラーです。変数 some の取得・代入をしているコードに問題がないか確認してください。

コンソールに Uncaught (in promise) TypeError: navigator.requestGPIOAccess is not a function などと表示される

関数 (メソッド) 呼び出ししようとしているがその関数が定義されていないというエラーです。この場合 navigator.requestGPIOAccess が関数ではないと言うことですが、polyfill スクリプトを読み込んでいないか、読み込みより前にアクセスしようとしている場合に発生します。

コンソールに Uncaught SyntaxError: await is only valid in async function などと表示される

await 文は async (非同期) 関数の中でのみ利用可能です。関数の中で await を使って非同期処理を行いたい場合、その関数を async 関数として宣言する必要があります。addEventListener など引数に関数を渡している場合に async を付け忘れているケースが多いので注意してください。

// 関数宣言:
async function wait100ms() { await sleep(100); }
// 匿名関数を使う場合:
element.addEventListener("click", async function() { await sleep(100); }, false);
// アロー(矢印)関数を使う場合
element.addEventListener("click", async () => { await sleep(100); }, false);

JS Bin のコンソールに error: ws error: [object Event] と表示される

コンソールに WebSocket connection to 'wss://localhost:33330/' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED などと表示される

CHIRIMEN Raspi3 のバックエンドサーバに接続できていません。デスクトップの reset.sh で再起動してください。

JavaScript から特定の URL にアクセスできない

コンソールに Failed to load https://...: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'https://...' is therefore not allowed access. などと表示される

コンソールに Access to fetch at 'https://...' from origin 'https://...' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. などと表示される

CHIRIMEN に限らず一般的な Web 開発でよく見かけるエラーです。Web には 同一オリジンポリシー (Same Origin Policy) というセキュリティ制約があり、JavaScript を読み込んでいるのと異なるドメインの URL には相手側のサーバが オリジン管理ソース共有 (CORS) で明示的に許可している場合以外は JavaScript のコード中で XMLHttpRequest や fetch からアクセスできません。

単純化して言えば、サーバからの HTTP レスポンスヘッダに access-control-allow-origin: * が付与されていれば JavaScript からのアクセスが許可されるため、任意の URL へのアクセスをプロキシ (中継) してレスポンスヘッダを勝手に追加してくれるようなサーバを用意すれば任意のドメインから任意の URL にアクセスが可能になります。

そのような機能を持った公開の CORS プロキシサービスには例えば https://cors-anywhere.herokuapp.com/https://cors.io/ などいろいろなものがあります。なお、これらのサービスの利用は本来のセキュリティ機能を無視するものであり、利用に際しては注意が必要です。あくまでもプライバシー情報などを含まないものについて、テストやプロトタイピング時だけに限って利用すべきです。

JS Bin や JS Fiddle で Web Bluetoooth, Web MIDI, WebRTC などが利用できない

Chrome 64 で Feature Policy というセキュリティ機構が導入され、iframe ページ内ではフレーム読み込み元のページの HTTP ヘッダで明示的な許可がされない限り、高度な機能が利用不可能になりました。JS Bin などのサービスでは読み込み結果を iframe 内に読み込んでいることが多いが、Feature Policy で許可をするヘッダの送信には未対応であるため、一部の Web API が利用できないことがあります。

これに該当する場合は開発ツールのコンソールに Feature Policy に関するエラーメッセージが表示されます。その場合にはコードをすべてローカルの HTML などで書いてそれをブラウザに読み込ませるようにしてください。

コードも配線も正しいのにとにかく動作しない!

いろいろな原因が考えらるため、ひとつずつ確認していく必要があります。

ハンズオン・ハッカソン・講義など、講師やチューターなどのいる時は、色々試して分からないときは一人で悩まず遠慮なく質問しましょう。 ひとつのことに悩んで糸口が見つけられないまま何十分も過ごさず、どんどん質問してデバッグテクニックや回避策などを教わってスキルを向上させていってください。