As all the exceptions are extending the base Exception class, you can get the code with the getCode() method:
<?php
try {
$collection->insert($duplicate_document, array('safe' => true));
} catch (MongoCursorException $e) {
printf("Error code is %d.\n", $e->getCode();
exit(1);
}
MongoCursorException クラス
(バージョン情報なし。おそらく SVN 版にしか存在しないでしょう)
導入
カーソルへの不正なアクセスや応答を受け取る際のエラーが原因です。 このエラーが発生するのは、単なるクエリではなく結果を受け取るリクエストであることに注意しましょう。 書き込みやコマンド、あるいはその他何らかの情報をデータベースに送って結果を待つ操作では MongoCursorException をスローすることがあります。 唯一の例外は new Mongo() (新しい接続の作成) で、これは MongoConnectionException しかスローしません。
このクラスはエラーメッセージを返します。 このメッセージを見れば、問題の調査の助けになり、 エラーコードに関連付けられた原因もわかります。
たとえば、次のように同じ _id のドキュメントを 2 件追加してみましょう。
<?php
try {
$collection->insert(array("_id" => 1), array("safe" => true));
$collection->insert(array("_id" => 1), array("safe" => true));
}
catch (MongoCursorException $e) {
echo "error message: ".$e->getMessage()."\n";
echo "error code: ".$e->getCode()."\n";
}
?>
error message: E11000 duplicate key error index: foo.bar.$_id_ dup key: { : 1 }
error code: 11000
よくあるエラーとそのコード、そして原因をまとめました。
-
cannot modify cursor after beginning iteration
コード: 0
クエリを実行した後で、クエリの設定を変えるメソッドをコールしました。 いったんカーソルをリセットしてからやりなおしてください。
An example:
<?php
try {
$cursor = $collection->find();
var_dump($cursor->getNext());
// getNext() でクエリを実行しているので、ここでリミットを指定しても遅すぎます
$cursor->limit(1);
}
catch (MongoCursorException $e) {
echo "error message: ".$e->getMessage()."\n";
echo "error code: ".$e->getCode()."\n";
}
// こうすれば、正しく動作します
$cursor->getNext();
$cursor->reset();
$cursor->limit(1);
?> -
Get next batch send errors
コード: 1
クエリをデータベースに送信できませんでした。 データベースが立ち上がっていることとネットワークが正常であることを確認してください。
-
cursor not found
コード: 2
ドライバがデータベースから結果を取得しようとしましたが、 データベース側にクエリが残っていませんでした。 たいていは、カーソルがサーバー側でタイムアウトしたことを意味します。 やりとりがない状況が数秒続くと、データベースはカーソルを消します (これを防ぐための方法は MongoCursor::immortal() を参照ください)。
例を示します。
<?php
try {
$cursor = $collection->find();
$cursor->getNext();
// 15 分間スリープします
sleep(60*15);
while ($cursor->hasNext()) {
$cursor->getNext();
}
}
catch (MongoCursorException $e) {
echo "error message: ".$e->getMessage()."\n";
echo "error code: ".$e->getCode()."\n";
}
?> -
cursor->buf.pos is null
コード: 3
これは、RAM から外れてしまったか、 その他の異常な状況になったことを意味します。
-
couldn't get response header
コード: 4
データベースあるいはネットワークがダウンしているときによく出るエラーです。 ドライバが接続からの応答を受け取れなかったことを意味します。
-
no db response
コード: 5
これはエラーではないかもしれません。たとえば、データベースの "shutdown" コマンドは何も応答を返しません。 しかし、もし何らかの応答を得ることを期待していたのにこのエラーになったのなら、 データベースがその応答を返さなかったことを意味します。
-
bad response length: %d, did the db assert?
コード: 6
これは、データベースの応答が 0 未満であることを意味します。 このエラーの原因は、おそらくネットワーク障害かデータベースの破損です。
-
incomplete header
コード: 7
めったにありませんが、 データベースの応答が正常にはじまったけれど途中で終わってしまった場合に発生します。 おそらくネットワークの問題でしょう。
-
incomplete response
コード: 8
めったにありませんが、 データベースの応答が正常にはじまったけれど途中で終わってしまった場合に発生します。 おそらくネットワークの問題でしょう。
-
couldn't find a response
コード: 9
キャッシュされていたレスポンスが見つけられませんでした。
-
error getting socket
コード: 10
ソケットが閉じられたか、エラーが発生しました。 ドライバは、(もし可能なら) 次の操作時に自動的に再接続しなければなりません。
-
couldn't find reply, please try again
コード: 11
ドライバは、リクエストに直接はマッチしないデータベースからの応答を保存します。 この例外が発生するのは、ドライバがすでにリクエストに対する応答を返した後で、 キャッシュ内に応答を見つけられなかったときです。
-
error getting database response: errstr
WSA error getting database response: errstr
"errstr" は、C のソケットから直接返ってきた入出力エラーです。 Windows では、エラーメッセージの先頭に "WSA" がつきます。
-
Timeout error
コード: 13
クエリが完了するのを待つ間に何かエラーが発生しました。
-
couldn't send query: <various>
コード: 14
送信時に C のソケットエラーが発生しました。
-
max number of retries exhausted, couldn't send query
Code: 19
最初の実行が何らかの原因で失敗したときに、ドライバは自動的に 「プレーンな」クエリ (コマンドではないもの) を何度か再送します。 これは、レプリカセットのフェイルオーバー時の例外の発生を減らし (それでも少しは発生しますが)、 一時的なネットワーク障害を取り繕うためです。
これは、何度実行しても結局データベースに再接続できなかったとき (たとえば、データベースにつながらないときなど) に発生します。
バージョン 1.2.2 で追加されました。
データベースから渡されたエラー
クエリの実行時に発生したデータベースのエラーは、常に MongoCursorExceptions を発生させなければなりません。 エラーメッセージとエラーコードはデータベースから直接送られるので、 対応するエラーをデータベースのログから見つけることができます。
一般的なデータベースエラーをいくつかまとめました。
-
E11000 duplicate key error index: foo.bar.$X dup key: { /* ... */ }
コード: 11000
キーが重複しているときのデータベースエラーです。
-
not master
コード: 10107, 13435 および 10058
マスタではないというエラーで、データベースから送られてきます。 これらのエラーが発生するとドライバは接続を切断し、 新しいマスタを探します。フェイルオーバーの際に実際に取得するエラーは "not master" ではないかもしれません。 これは、マスタの変更がいつ発生したのかに依存します。
クラス概要
Not sure if it's intentional but all the properties on CursorException (including code) are protected or private, so you will have to handle all CursorExceptions the same.
