-
Type: Improvement
-
Resolution: Works as Designed
-
Priority: Major - P3
-
None
-
Affects Version/s: None
-
Component/s: Error Handling
-
None
-
(copied to CRM)
Similar cases have been closed in the past (CSHARP-155, CSHARP-474, CSHARP-153) however the issue still persists.
For example:
Unable to find source-code formatter for language: csharp. Available languages are: actionscript, ada, applescript, bash, c, c#, c++, cpp, css, erlang, go, groovy, haskell, html, java, javascript, js, json, lua, none, nyan, objc, perl, php, python, r, rainbow, ruby, scala, sh, sql, swift, visualbasic, xml, yaml
[TestMethod] public void ShouldRaiseBetterErrors() { const string CONN = "mongodb://localhost:27017"; var client = new MongoClient(MongoUrl.Create(CONN)); var database = client.GetDatabase("test"); database.DropCollection("foo"); var collection = database.GetCollection<BsonDocument>("foo"); var search = "Test\0Test"; var regex = new BsonRegularExpression(string.Format(".*{0}.*", search), "i"); var filter = Builders<BsonDocument>.Filter.Gt("_id", regex); try { var result = collection.Find(filter).FirstOrDefault(); } catch (ArgumentException e) when (e.Message == "A CString cannot contain null bytes." && e.ParamName == "value") { throw new ApplicationException("You are trying to query with a string that contains a null character, this is not supported"); } }
In the above example, when a CStringUtf8Encoding detects a null byte an ArgumentException is raised.
As this exception can be raised as any part of a command, to capture context this specific exception would need to be caught and re-thrown.
A more appropriate method would be to ensure errors are all enumerated and error codes accessible from the exception instance such as:
Unable to find source-code formatter for language: csharp. Available languages are: actionscript, ada, applescript, bash, c, c#, c++, cpp, css, erlang, go, groovy, haskell, html, java, javascript, js, json, lua, none, nyan, objc, perl, php, python, r, rainbow, ruby, scala, sh, sql, swift, visualbasic, xml, yaml
public enum ErrorCodes { //... InvalidCString = 10001 //... } // ... namespace MongoDB.Bson.IO { internal static class CStringUtf8Encoding { public static int GetBytes(string value, byte[] bytes, int byteIndex, UTF8Encoding fallbackEncoding) { var charLength = value.Length; var initialByteIndex = byteIndex; for (var charIndex = 0; charIndex < charLength; charIndex++) { var c = (int)value[charIndex]; if (c == 0) { throw new MongoDriverException { Code = ErrorCodes.InvalidCString, Message = "A CString cannot contain null bytes.", ... }); } // ... } // ... } } }
This approach is similar to what the server does with error_codes.yml.
Note that a search of the mongodb/mongo-csharp-driver for "throw new ArgumentException" provides a number of similar examples.