Uploaded image for project: 'C# Driver'
  1. C# Driver
  2. CSHARP-3272

Don't throw non-specific Exceptions

    • Type: Icon: Improvement Improvement
    • Resolution: Works as Designed
    • Priority: Icon: Major - P3 Major - P3
    • None
    • Affects Version/s: None
    • Component/s: Error Handling
    • None

      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.

            Assignee:
            robert@mongodb.com Robert Stam
            Reporter:
            alex.bevilacqua@mongodb.com Alex Bevilacqua
            Votes:
            6 Vote for this issue
            Watchers:
            5 Start watching this issue

              Created:
              Updated:
              Resolved: