Skip to content

Commit

Permalink
Merge pull request #46 from matteobortolazzo/dev
Browse files Browse the repository at this point in the history
Release 1.1.3
  • Loading branch information
Matteo Bortolazzo authored Jun 14, 2019
2 parents 3d68c0f + a6f2f63 commit 866e4da
Show file tree
Hide file tree
Showing 9 changed files with 163 additions and 70 deletions.
7 changes: 6 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
# 1.1.2 (2019-06-08)
# 1.1.3 (2019-06-14)

## Bug Fixes
* **Exception:** Fixing null reference exception and poor exception handling. ([#PR45](https://github.com/matteobortolazzo/couchdb-net/pull/45))

# 1.1.2 (2019-06-08)

## Bug Fixes
* **Client:** Prevent deadlocks when run against .NET Framework. ([#PR43](https://github.com/matteobortolazzo/couchdb-net/pull/43))
Expand Down
2 changes: 1 addition & 1 deletion LATEST_CHANGE.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
## Bug Fixes
* **Client:** Prevent deadlocks when run against .NET Framework. ([#PR43](https://github.com/matteobortolazzo/couchdb-net/pull/43))
* **Exception:** Fixing null reference exception and poor exception handling. ([#PR45](https://github.com/matteobortolazzo/couchdb-net/pull/45))
23 changes: 16 additions & 7 deletions src/CouchDB.Driver/CouchQueryProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Runtime.ExceptionServices;

namespace CouchDB.Driver
{
Expand Down Expand Up @@ -37,14 +38,22 @@ public override object Execute(Expression expression, bool completeResponse)
// Remove from the expressions tree all IQueryable methods not supported by CouchDB and put them into the list
var unsupportedMethodCallExpressions = new List<MethodCallExpression>();
expression = RemoveUnsupportedMethodExpressions(expression, out var hasUnsupportedMethods, unsupportedMethodCallExpressions);

var body = Translate(ref expression);
Type elementType = TypeSystem.GetElementType(expression.Type);

// Create generic GetCouchList method and invoke it, sending the request to CouchDB
MethodInfo method = typeof(CouchQueryProvider).GetMethod(nameof(CouchQueryProvider.GetCouchList));
MethodInfo generic = method.MakeGenericMethod(elementType);
var result = generic.Invoke(this, new[] { body });
object result = null;
try
{
result = generic.Invoke(this, new[] { body });
}
catch (TargetInvocationException ex)
{
ExceptionDispatchInfo.Capture(ex.InnerException).Throw();
}

// If no unsupported methods, return the result
if (!hasUnsupportedMethods)
Expand Down Expand Up @@ -73,7 +82,7 @@ private string Translate(ref Expression e)
}

public object GetCouchList<T>(string body)
{
{
FindResult<T> result = _flurlClient
.Request(_connectionString)
.AppendPathSegments(_db, "_find")
Expand All @@ -82,7 +91,7 @@ public object GetCouchList<T>(string body)
.SendRequest();

var couchList = new CouchList<T>(result.Docs.ToList(), result.Bookmark, result.ExecutionStats);
return couchList;
return couchList;
}

private Expression RemoveUnsupportedMethodExpressions(Expression expression, out bool hasUnsupportedMethods, IList<MethodCallExpression> unsupportedMethodCallExpressions)
Expand Down Expand Up @@ -177,7 +186,7 @@ MethodInfo FindEnumerableMethod()
throw;
}
}

private object GetArgumentValueFromExpression(Expression e)
{
if (e is ConstantExpression c)
Expand All @@ -190,7 +199,7 @@ private object GetArgumentValueFromExpression(Expression e)
}
throw new NotImplementedException($"Expression of type {e.NodeType} not supported.");
}

private static MethodInfo FindEnumerableMinMax(MethodInfo queryableMethodInfo)
{
Type[] genericParams = queryableMethodInfo.GetGenericArguments();
Expand All @@ -203,6 +212,6 @@ private static MethodInfo FindEnumerableMinMax(MethodInfo queryableMethodInfo)
enumerableMethodInfo.ReturnType == genericParams[1];
});
return finalMethodInfo;
}
}
}
}
14 changes: 6 additions & 8 deletions src/CouchDB.Driver/Exceptions/CouchConflictException.cs
Original file line number Diff line number Diff line change
@@ -1,16 +1,14 @@
namespace CouchDB.Driver.Exceptions
using CouchDB.Driver.DTOs;
using System;

namespace CouchDB.Driver.Exceptions
{
/// <summary>
/// The exception that is thrown when there is a conflict.
/// </summary>
public class CouchConflictException : CouchException
{
/// <summary>
/// Creates a new instance of CouchConflictException.
/// </summary>
/// <param name="message">Error message</param>
/// <param name="reason">Error reason</param>
public CouchConflictException(string message, string reason) : base(message, reason) { }
internal CouchConflictException(CouchError couchError, Exception innerException) : base(couchError, innerException) { }

public CouchConflictException()
{
Expand All @@ -20,7 +18,7 @@ public CouchConflictException(string message) : base(message)
{
}

public CouchConflictException(string message, System.Exception innerException) : base(message, innerException)
public CouchConflictException(string message, Exception innerException) : base(message, innerException)
{
}
}
Expand Down
24 changes: 19 additions & 5 deletions src/CouchDB.Driver/Exceptions/CouchException.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using CouchDB.Driver.DTOs;
using System;

namespace CouchDB.Driver.Exceptions
{
Expand All @@ -12,18 +13,31 @@ public class CouchException : Exception
/// </summary>
/// <param name="message">Error message</param>
/// <param name="reason">Error reason</param>
public CouchException(string message, string reason) : base(message, new Exception(reason)) { }
public CouchException(string message, string reason) : this(message, reason, null)
{
}

public CouchException() : this(null, null, null)
{
}

public CouchException()
public CouchException(string message) : this(message, null, null)
{
}

public CouchException(string message) : base(message)
public CouchException(string message, Exception innerException) : this(message, null, innerException)
{
}

public CouchException(string message, Exception innerException) : base(message, innerException)
internal CouchException(CouchError couchError, Exception innerException) : this(couchError?.Error, couchError?.Reason, innerException)
{
}

public CouchException(string message, string reason, Exception innerException) : base(message, innerException)
{
Reason = reason;
}

public string Reason { get; }
}
}
14 changes: 6 additions & 8 deletions src/CouchDB.Driver/Exceptions/CouchNoIndexException.cs
Original file line number Diff line number Diff line change
@@ -1,16 +1,14 @@
namespace CouchDB.Driver.Exceptions
using CouchDB.Driver.DTOs;
using System;

namespace CouchDB.Driver.Exceptions
{
/// <summary>
/// The exception that is thrown when there is no index for the query.
/// </summary>
public class CouchNoIndexException : CouchException
{
/// <summary>
/// Creates a new instance of CouchNoIndexException.
/// </summary>
/// <param name="message">Error message</param>
/// <param name="reason">Error reason</param>
public CouchNoIndexException(string message, string reason) : base(message, reason) { }
internal CouchNoIndexException(CouchError couchError, Exception innerException) : base(couchError, innerException) { }

public CouchNoIndexException()
{
Expand All @@ -20,7 +18,7 @@ public CouchNoIndexException(string message) : base(message)
{
}

public CouchNoIndexException(string message, System.Exception innerException) : base(message, innerException)
public CouchNoIndexException(string message, Exception innerException) : base(message, innerException)
{
}
}
Expand Down
14 changes: 6 additions & 8 deletions src/CouchDB.Driver/Exceptions/CouchNotFoundException.cs
Original file line number Diff line number Diff line change
@@ -1,16 +1,14 @@
namespace CouchDB.Driver.Exceptions
using CouchDB.Driver.DTOs;
using System;

namespace CouchDB.Driver.Exceptions
{
/// <summary>
/// The exception that is thrown when something is not found.
/// </summary>
public class CouchNotFoundException : CouchException
{
/// <summary>
/// Creates a new instance of CouchNotFoundException.
/// </summary>
/// <param name="message">Error message</param>
/// <param name="reason">Error reason</param>
public CouchNotFoundException(string message, string reason) : base(message, reason) { }
internal CouchNotFoundException(CouchError couchError, Exception innerException) : base(couchError, innerException) { }

public CouchNotFoundException()
{
Expand All @@ -20,7 +18,7 @@ public CouchNotFoundException(string message) : base(message)
{
}

public CouchNotFoundException(string message, System.Exception innerException) : base(message, innerException)
public CouchNotFoundException(string message, Exception innerException) : base(message, innerException)
{
}
}
Expand Down
42 changes: 13 additions & 29 deletions src/CouchDB.Driver/Helpers/RequestsHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,41 +23,25 @@ public static async Task<T> SendRequestAsync<T>(this Task<T> asyncRequest)
}
catch (FlurlHttpException ex)
{
CouchError couchError;
try
{
couchError = await ex.GetResponseJsonAsync<CouchError>().ConfigureAwait(false);
}
catch
CouchError couchError = await ex.GetResponseJsonAsync<CouchError>().ConfigureAwait(false);

if (couchError == null)
{
throw;
couchError = new CouchError();
}

if (couchError != null)
switch (ex.Call.HttpStatus)
{
switch (ex.Call.HttpStatus)
{
case HttpStatusCode.Conflict:
throw couchError.NewCouchExteption(typeof(CouchConflictException));
case HttpStatusCode.NotFound:
throw couchError.NewCouchExteption(typeof(CouchNotFoundException));
case HttpStatusCode.BadRequest:
if (couchError.Error == "no_usable_index")
{
throw couchError.NewCouchExteption(typeof(CouchNoIndexException));
}
break;
}
case HttpStatusCode.Conflict:
throw new CouchConflictException(couchError, ex);
case HttpStatusCode.NotFound:
throw new CouchNotFoundException(couchError, ex);
case HttpStatusCode.BadRequest when couchError.Error == "no_usable_index":
throw new CouchNoIndexException(couchError, ex);
default:
throw new CouchException(couchError, ex);
}
throw new CouchException(couchError.Error, couchError.Reason);
}
}

private static Exception NewCouchExteption(this CouchError e, Type type)
{
ConstructorInfo ctor = type.GetConstructor(new[] { typeof(string), typeof(string) });
var exception = (CouchException)ctor.Invoke(new string[] { e.Error, e.Reason });
return exception;
}
}
}
Loading

0 comments on commit 866e4da

Please sign in to comment.