static bool _mongoc_cursor_unwrap_failure (mongoc_cursor_t *cursor) { bson_iter_t iter; bson_t b; ENTRY; bson_return_val_if_fail(cursor, false); if (cursor->rpc.header.opcode != MONGOC_OPCODE_REPLY) { bson_set_error(&cursor->error, MONGOC_ERROR_PROTOCOL, MONGOC_ERROR_PROTOCOL_INVALID_REPLY, "Received rpc other than OP_REPLY."); RETURN(true); } if ((cursor->rpc.reply.flags & MONGOC_REPLY_QUERY_FAILURE)) { if (_mongoc_rpc_reply_get_first(&cursor->rpc.reply, &b)) { _mongoc_cursor_populate_error(cursor, &b, &cursor->error); bson_destroy(&b); } else { bson_set_error(&cursor->error, MONGOC_ERROR_QUERY, MONGOC_ERROR_QUERY_FAILURE, "Unknown query failure."); } RETURN(true); } else if (cursor->is_command) { if (_mongoc_rpc_reply_get_first (&cursor->rpc.reply, &b)) { if (bson_iter_init_find (&iter, &b, "ok")) { if (bson_iter_as_bool (&iter)) { RETURN (false); } else { _mongoc_cursor_populate_error (cursor, &b, &cursor->error); bson_destroy (&b); RETURN (true); } } } else { bson_set_error (&cursor->error, MONGOC_ERROR_BSON, MONGOC_ERROR_BSON_INVALID, "Failed to decode document from the server."); RETURN (true); } } if ((cursor->rpc.reply.flags & MONGOC_REPLY_CURSOR_NOT_FOUND)) { bson_set_error(&cursor->error, MONGOC_ERROR_CURSOR, MONGOC_ERROR_CURSOR_INVALID_CURSOR, "The cursor is invalid or has expired."); RETURN(true); } RETURN(false); }
/* returns true if the reply is a server error */ static bool _mongoc_rpc_parse_error (mongoc_rpc_t *rpc, bool is_command, int32_t error_api_version, bson_error_t *error /* OUT */) { bson_t b; bool r; ENTRY; BSON_ASSERT (rpc); if (rpc->header.opcode != MONGOC_OPCODE_REPLY) { bson_set_error(error, MONGOC_ERROR_PROTOCOL, MONGOC_ERROR_PROTOCOL_INVALID_REPLY, "Received rpc other than OP_REPLY."); RETURN(true); } if (is_command) { if (_mongoc_rpc_reply_get_first (&rpc->reply, &b)) { r = _mongoc_populate_cmd_error (&b, error_api_version, error); bson_destroy(&b); RETURN (r); } else { bson_set_error (error, MONGOC_ERROR_BSON, MONGOC_ERROR_BSON_INVALID, "Failed to decode document from the server."); RETURN (true); } } else if ((rpc->reply.flags & MONGOC_REPLY_QUERY_FAILURE)) { if (_mongoc_rpc_reply_get_first (&rpc->reply, &b)) { _mongoc_populate_query_error (&b, error_api_version, error); bson_destroy (&b); } else { bson_set_error (error, MONGOC_ERROR_QUERY, MONGOC_ERROR_QUERY_FAILURE, "Unknown query failure."); } RETURN (true); } if ((rpc->reply.flags & MONGOC_REPLY_CURSOR_NOT_FOUND)) { bson_set_error(error, MONGOC_ERROR_CURSOR, MONGOC_ERROR_CURSOR_INVALID_CURSOR, "The cursor is invalid or has expired."); RETURN(true); } RETURN(false); }
bool _mongoc_client_recv_gle (mongoc_client_t *client, uint32_t hint, bson_t **gle_doc, bson_error_t *error) { mongoc_buffer_t buffer; mongoc_rpc_t rpc; bson_iter_t iter; bool ret = false; bson_t b; ENTRY; bson_return_val_if_fail (client, false); bson_return_val_if_fail (hint, false); if (gle_doc) { *gle_doc = NULL; } _mongoc_buffer_init (&buffer, NULL, 0, NULL, NULL); if (!_mongoc_cluster_try_recv (&client->cluster, &rpc, &buffer, hint, error)) { GOTO (cleanup); } if (rpc.header.opcode != MONGOC_OPCODE_REPLY) { bson_set_error (error, MONGOC_ERROR_PROTOCOL, MONGOC_ERROR_PROTOCOL_INVALID_REPLY, "Received message other than OP_REPLY."); GOTO (cleanup); } if (_mongoc_rpc_reply_get_first (&rpc.reply, &b)) { if (gle_doc) { *gle_doc = bson_copy (&b); } if ((rpc.reply.flags & MONGOC_REPLY_QUERY_FAILURE)) { _bson_to_error (&b, error); bson_destroy (&b); GOTO (cleanup); } if (!bson_iter_init_find (&iter, &b, "ok") || BSON_ITER_HOLDS_DOUBLE (&iter)) { if (bson_iter_double (&iter) == 0.0) { _bson_to_error (&b, error); } } bson_destroy (&b); } ret = true; cleanup: _mongoc_buffer_destroy (&buffer); RETURN (ret); }
bool _mongoc_client_recv_gle (mongoc_client_t *client, mongoc_server_stream_t *server_stream, bson_t **gle_doc, bson_error_t *error) { mongoc_buffer_t buffer; mongoc_rpc_t rpc; bson_iter_t iter; bool ret = false; bson_t b; ENTRY; BSON_ASSERT (client); BSON_ASSERT (server_stream); if (gle_doc) { *gle_doc = NULL; } _mongoc_buffer_init (&buffer, NULL, 0, NULL, NULL); if (!mongoc_cluster_try_recv (&client->cluster, &rpc, &buffer, server_stream, error)) { mongoc_topology_invalidate_server (client->topology, server_stream->sd->id); GOTO (cleanup); } if (rpc.header.opcode != MONGOC_OPCODE_REPLY) { bson_set_error (error, MONGOC_ERROR_PROTOCOL, MONGOC_ERROR_PROTOCOL_INVALID_REPLY, "Received message other than OP_REPLY."); GOTO (cleanup); } if (_mongoc_rpc_reply_get_first (&rpc.reply, &b)) { if ((rpc.reply.flags & MONGOC_REPLY_QUERY_FAILURE)) { _bson_to_error (&b, error); bson_destroy (&b); GOTO (cleanup); } if (gle_doc) { *gle_doc = bson_copy (&b); } if (!bson_iter_init_find (&iter, &b, "ok") || BSON_ITER_HOLDS_DOUBLE (&iter)) { if (bson_iter_double (&iter) == 0.0) { _bson_to_error (&b, error); } } bson_destroy (&b); ret = true; } cleanup: _mongoc_buffer_destroy (&buffer); RETURN (ret); }