Skip to content
Browse files

[feature] stdlib: Added Bson.error type.

  • Loading branch information...
1 parent 474d6d6 commit f79e8c7b7cdf1a9cdeb77ad3b2d0458fd7cdfc31 @nrs135 nrs135 committed Oct 28, 2011
Showing with 62 additions and 3 deletions.
  1. +60 −1 stdlib/apis/mongo/bson.opa
  2. +2 −2 stdlib/apis/mongo/mongo.opa
View
61 stdlib/apis/mongo/bson.opa
@@ -109,6 +109,19 @@ type Bson.element = { name:string; value:Bson.value }
type Bson.document = list(Bson.element)
/**
+ * A generic error status type for OPA.
+ * Some commands will not be directly convertible into
+ * this, others will. See [error_of_document].
+ **/
+type Bson.error = {
+ ok: Bson.register(Bson.int32);
+ err: Bson.register(string);
+ code: Bson.register(Bson.int32);
+ n: Bson.register(Bson.int32);
+ errmsg: Bson.register(string);
+}
+
+/**
* Helper functions for constructing Bson values.
*
* Short names intended to be abbreviations for {name=...; value={Xyz=...}}.
@@ -459,7 +472,7 @@ Bson = {{
* returned by mongo. Which may be an error even if the
* outcome is "success".
**/
- string_of_doc(doc:Bson.document): string =
+ string_of_doc_error(doc:Bson.document): string =
ok =
match find_int(doc,"ok") with
| {some=0} -> "<not ok>"
@@ -473,6 +486,52 @@ Bson = {{
String.concat(" ",List.filter((s -> s != ""),[ok,err,code,n,errmsg]))
/**
+ * Same as [string_of_doc] but using an OPA type.
+ **/
+ string_of_error(error:Bson.error): string =
+ ok =
+ match error.ok with
+ | {present=0} -> "<not ok>"
+ | {present=1} -> "<ok>"
+ | {present=n} -> "<not ok> (Weird ok number {n})"
+ | {absent} -> "<unknown ok status>"
+ err = match error.err with | {present=""} -> "" | {present=err} -> "<err=\"{err}\">" | {absent} -> ""
+ code = match error.code with | {present=code} -> "<code={code}>" | {absent} -> ""
+ n = match error.n with | {present=n} -> "<n={n}>" | {absent} -> ""
+ errmsg = match error.errmsg with | {present=""} -> "" | {present=errmsg} -> "<errmsg=\"{errmsg}\">" | {absent} -> ""
+ String.concat(" ",List.filter((s -> s != ""),[ok,err,code,n,errmsg]))
+
+ /**
+ * We can't always use bson_to_opa to extract the error-relevant
+ * fields from a MongoDB reply document, there might be other
+ * arbitrary fields present. Here we extract just those fields
+ * which are relevant to the error status. Should work on any
+ * document.
+ **/
+ error_of_document(doc:Bson.document): Bson.error =
+ { ok=
+ match find_int(doc,"ok") with
+ | {some=n} -> {present=n}
+ | {none} -> {absent};
+ err=
+ match find_string(doc, "err") with
+ | {some=err} -> {present=err}
+ | {none} -> {absent};
+ code=
+ match find_int(doc,"code") with
+ | {some=code} -> {present=code}
+ | {none} -> {absent};
+ n=
+ match find_int(doc,"n") with
+ | {some=n} -> {present=n}
+ | {none} -> {absent};
+ errmsg=
+ match find_string(doc, "errmsg") with
+ | {some=errmsg} -> {present=errmsg}
+ | {none} -> {absent};
+ }
+
+ /**
* OPA to Bson
**/
View
4 stdlib/apis/mongo/mongo.opa
@@ -141,11 +141,11 @@ Mongo = {{
string_of_failure(failure:Mongo.failure): string =
match failure with
| {Error=str} -> str
- | {DocError=doc} -> Bson.string_of_doc(doc)
+ | {DocError=doc} -> Bson.string_of_doc_error(doc)
string_of_result(result:Mongo.result): string =
match result with
- | {success=doc} -> Bson.string_of_doc(doc)
+ | {success=doc} -> Bson.string_of_doc_error(doc)
| {~failure} -> string_of_failure(failure)
string_of_outcome(result:outcome('a,'b), success_to_str:'a->string, failure_to_str:'b->string): string =

0 comments on commit f79e8c7

Please sign in to comment.
Something went wrong with that request. Please try again.