Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #585 from SignalR/Issue#515
Added custom SignalR error handling capability - Fixed #515
- Loading branch information
Showing
7 changed files
with
199 additions
and
11 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
using System; | ||
using System.IO; | ||
using System.Net; | ||
|
||
namespace SignalR.Client | ||
{ | ||
public static class ErrorExtensions | ||
{ | ||
/// <summary> | ||
/// Simplifies error recognition by unwrapping complex exceptions. | ||
/// </summary> | ||
/// <param name="ex">The thrown exception.</param> | ||
/// <returns>An unwrapped exception in the form of a SignalRError.</returns> | ||
public static SignalRError GetError(this Exception ex) | ||
{ | ||
ex = ex.Unwrap(); | ||
var wex = ex as WebException; | ||
|
||
var error = new SignalRError(ex); | ||
|
||
if (wex != null && wex.Response != null) | ||
{ | ||
var response = wex.Response as HttpWebResponse; | ||
if (response != null) | ||
{ | ||
error.SetResponse(response); | ||
error.StatusCode = response.StatusCode; | ||
Stream originStream = response.GetResponseStream(); | ||
|
||
if (originStream.CanRead) | ||
{ | ||
// We need to copy the stream over and not consume it all on "ReadToEnd". If we consumed the entire stream GetError | ||
// would only be able to be called once per Exception, otherwise you get inconsistent ResponseBody results. | ||
Stream stream = Clone(originStream); | ||
|
||
// Consume our copied stream | ||
using (var sr = new StreamReader(stream)) | ||
{ | ||
error.ResponseBody = sr.ReadToEnd(); | ||
} | ||
} | ||
} | ||
} | ||
|
||
return error; | ||
} | ||
|
||
private static Stream Clone(Stream source) | ||
{ | ||
var cloned = new MemoryStream(); | ||
byte[] buffer = new byte[2048];// Copy up to 2048 bytes at a time | ||
int copiedBytes;// Maintains how many bytes were read | ||
|
||
// Read bytes and copy them into a buffer making sure not to trigger the dispose | ||
while ((copiedBytes = source.Read(buffer, 0, buffer.Length)) > 0) | ||
{ | ||
// Write the copied bytes from the buffer into the cloned stream | ||
cloned.Write(buffer, 0, copiedBytes); | ||
} | ||
|
||
// Move the stream pointers back to the original start locations | ||
if (source.CanSeek) | ||
{ | ||
source.Seek(0, 0); | ||
} | ||
|
||
cloned.Seek(0, 0); | ||
|
||
return cloned; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
using System; | ||
using System.Net; | ||
|
||
namespace SignalR.Client | ||
{ | ||
/// <summary> | ||
/// Represents errors that are thrown by the SignalR client | ||
/// </summary> | ||
public class SignalRError : IDisposable | ||
{ | ||
private HttpWebResponse _response; | ||
|
||
/// <summary> | ||
/// Create custom SignalR based error. | ||
/// </summary> | ||
/// <param name="exception">The exception to unwrap</param> | ||
public SignalRError(Exception exception) | ||
{ | ||
Exception = exception; | ||
} | ||
|
||
/// <summary> | ||
/// Capture the response so we can dispose of it later | ||
/// </summary> | ||
/// <param name="response">The HttpWebResponse associated with the Exception, assuming its a WebException</param> | ||
public void SetResponse(HttpWebResponse response) | ||
{ | ||
_response = response; | ||
} | ||
|
||
/// <summary> | ||
/// The status code of the error (if it was a WebException) | ||
/// </summary> | ||
public HttpStatusCode StatusCode { get; set; } | ||
|
||
/// <summary> | ||
/// The response body of the error, if it was a WebException and the response is readable | ||
/// </summary> | ||
public string ResponseBody { get; set; } | ||
|
||
/// <summary> | ||
/// The unwrapped underlying exception | ||
/// </summary> | ||
public Exception Exception { get; private set; } | ||
|
||
/// <summary> | ||
/// Allow a SignalRError to be directly written to an output stream | ||
/// </summary> | ||
/// <returns>Exception error</returns> | ||
public override string ToString() | ||
{ | ||
return Exception.ToString(); | ||
} | ||
|
||
/// <summary> | ||
/// Dispose of the response | ||
/// </summary> | ||
public void Dispose() | ||
{ | ||
if (_response != null) | ||
{ | ||
_response.Close(); | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters