From 6d85e752e1fb75ebdf4b68ac1c995e248d1f5fcb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C5=82awomir=20Rosiek?= Date: Wed, 31 May 2017 20:06:06 +0200 Subject: [PATCH] Throwing HttpInvocationException instead of generic Exception --- .../HostingModels/HttpNodeInstance.cs | 37 ++++++++++++++++++- .../TypeScript/HttpNodeInstanceEntryPoint.ts | 5 ++- 2 files changed, 39 insertions(+), 3 deletions(-) diff --git a/src/Microsoft.AspNetCore.NodeServices/HostingModels/HttpNodeInstance.cs b/src/Microsoft.AspNetCore.NodeServices/HostingModels/HttpNodeInstance.cs index b1b0fe9..8dd896b 100644 --- a/src/Microsoft.AspNetCore.NodeServices/HostingModels/HttpNodeInstance.cs +++ b/src/Microsoft.AspNetCore.NodeServices/HostingModels/HttpNodeInstance.cs @@ -21,6 +21,7 @@ namespace Microsoft.AspNetCore.NodeServices.HostingModels /// internal class HttpNodeInstance : OutOfProcessNodeInstance { + private readonly static int streamBufferSize = 16 * 1024; private static readonly Regex PortMessageRegex = new Regex(@"^\[Microsoft.AspNetCore.NodeServices.HttpNodeHost:Listening on port (\d+)\]$"); @@ -67,8 +68,10 @@ namespace Microsoft.AspNetCore.NodeServices.HostingModels if (!response.IsSuccessStatusCode) { // Unfortunately there's no true way to cancel ReadAsStringAsync calls, hence AbandonIfCancelled - var responseErrorString = await response.Content.ReadAsStringAsync().OrThrowOnCancellation(cancellationToken); - throw new Exception("Call to Node module failed with error: " + responseErrorString); + var responseJson = await response.Content.ReadAsStringAsync().OrThrowOnCancellation(cancellationToken); + var responseError = JsonConvert.DeserializeObject(responseJson, jsonSerializerSettings); + + throw new NodeInvocationException(responseError.ErrorMessage, responseError.ErrorDetails); } var responseContentType = response.Content.Headers.ContentType; @@ -136,5 +139,35 @@ namespace Microsoft.AspNetCore.NodeServices.HostingModels _disposed = true; } } + + private static async Task ReadJsonAsync(Stream stream, CancellationToken cancellationToken) + { + var json = Encoding.UTF8.GetString(await ReadAllBytesAsync(stream, cancellationToken)); + return JsonConvert.DeserializeObject(json, jsonSerializerSettings); + } + + private static async Task ReadAllBytesAsync(Stream input, CancellationToken cancellationToken) + { + byte[] buffer = new byte[streamBufferSize]; + + using (var ms = new MemoryStream()) + { + int read; + while ((read = await input.ReadAsync(buffer, 0, buffer.Length, cancellationToken)) > 0) + { + ms.Write(buffer, 0, read); + } + + return ms.ToArray(); + } + } + +#pragma warning disable 649 // These properties are populated via JSON deserialization + private class RpcJsonResponse + { + public string ErrorMessage { get; set; } + public string ErrorDetails { get; set; } + } +#pragma warning restore 649 } } diff --git a/src/Microsoft.AspNetCore.NodeServices/TypeScript/HttpNodeInstanceEntryPoint.ts b/src/Microsoft.AspNetCore.NodeServices/TypeScript/HttpNodeInstanceEntryPoint.ts index 9b51bf1..31f6376 100644 --- a/src/Microsoft.AspNetCore.NodeServices/TypeScript/HttpNodeInstanceEntryPoint.ts +++ b/src/Microsoft.AspNetCore.NodeServices/TypeScript/HttpNodeInstanceEntryPoint.ts @@ -86,5 +86,8 @@ function readRequestBodyAsJson(request, callback) { function respondWithError(res: http.ServerResponse, errorValue: any) { res.statusCode = 500; - res.end(errorValue.stack || errorValue.toString()); + res.end(JSON.stringify({ + errorMessage: errorValue.message || errorValue, + errorDetails: errorValue.stack || null + })); }