Skip to content

Commit 523a8b1

Browse files
committed
Added NotFound handling
1 parent 27b5cbb commit 523a8b1

File tree

7 files changed

+109
-48
lines changed

7 files changed

+109
-48
lines changed

sample/PSWebApi.OwinSample/PSWebApi.OwinSample.csproj

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,8 @@
4040
<WarningLevel>4</WarningLevel>
4141
</PropertyGroup>
4242
<ItemGroup>
43-
<Reference Include="DataBooster.PSWebApi, Version=1.1.8.0, Culture=neutral, PublicKeyToken=ee1eb06d9feeb8dc, processorArchitecture=MSIL">
44-
<HintPath>..\..\packages\DataBooster.PSWebApi.1.1.8\lib\net45\DataBooster.PSWebApi.dll</HintPath>
43+
<Reference Include="DataBooster.PSWebApi, Version=1.1.8.1, Culture=neutral, PublicKeyToken=ee1eb06d9feeb8dc, processorArchitecture=MSIL">
44+
<HintPath>..\..\packages\DataBooster.PSWebApi.1.1.8.1\lib\net45\DataBooster.PSWebApi.dll</HintPath>
4545
<Private>True</Private>
4646
</Reference>
4747
<Reference Include="Microsoft.CSharp" />

sample/PSWebApi.OwinSample/Properties/AssemblyInfo.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,5 +31,5 @@
3131
//
3232
// You can specify all the values or you can default the Revision and Build Numbers
3333
// by using the '*' as shown below:
34-
[assembly: AssemblyVersion("1.1.8.0")]
35-
[assembly: AssemblyFileVersion("1.1.8.0")]
34+
[assembly: AssemblyVersion("1.1.8.1")]
35+
[assembly: AssemblyFileVersion("1.1.8.1")]

sample/PSWebApi.OwinSample/packages.config

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<?xml version="1.0" encoding="utf-8"?>
22
<packages>
3-
<package id="DataBooster.PSWebApi" version="1.1.8" targetFramework="net45" />
3+
<package id="DataBooster.PSWebApi" version="1.1.8.1" targetFramework="net45" />
44
<package id="Microsoft.AspNet.Cors" version="5.2.3" targetFramework="net45" />
55
<package id="Microsoft.AspNet.WebApi.Client" version="5.2.3" targetFramework="net45" />
66
<package id="Microsoft.AspNet.WebApi.Core" version="5.2.3" targetFramework="net45" />

src/DataBooster.PSWebApi/PSControllerExtensions.async.cs

Lines changed: 41 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
using System.Threading.Tasks;
1212
using System.Collections.Generic;
1313
using System.Management.Automation;
14+
using System.ComponentModel;
1415

1516
namespace DataBooster.PSWebApi
1617
{
@@ -42,15 +43,22 @@ public async static Task<HttpResponseMessage> InvokePowerShellAsync(this ApiCont
4243
if (!string.IsNullOrWhiteSpace(converter.ConversionCmdlet))
4344
ps.AddCommand(converter.ConversionCmdlet, true).Commands.AddParameters(converter.CmdletParameters);
4445

45-
string stringResult = GetPsResult(await ps.InvokeAsync(cancellationToken).ConfigureAwait(false), encoding);
46+
try
47+
{
48+
string stringResult = GetPsResult(await ps.InvokeAsync(cancellationToken).ConfigureAwait(false), encoding);
4649

47-
ps.CheckErrors(cancellationToken);
50+
ps.CheckErrors(cancellationToken);
4851

49-
StringContent responseContent = new StringContent(stringResult, encoding, contentNegotiator.NegotiatedMediaType.MediaType);
52+
StringContent responseContent = new StringContent(stringResult, encoding, contentNegotiator.NegotiatedMediaType.MediaType);
5053

51-
responseContent.Headers.SetContentHeader(ps.Streams);
54+
responseContent.Headers.SetContentHeader(ps.Streams);
5255

53-
return new HttpResponseMessage(string.IsNullOrEmpty(stringResult) ? HttpStatusCode.NoContent : HttpStatusCode.OK) { Content = responseContent };
56+
return new HttpResponseMessage(string.IsNullOrEmpty(stringResult) ? HttpStatusCode.NoContent : HttpStatusCode.OK) { Content = responseContent };
57+
}
58+
catch (CommandNotFoundException)
59+
{
60+
return new HttpResponseMessage(HttpStatusCode.NotFound);
61+
}
5462
}
5563
}
5664

@@ -91,22 +99,36 @@ public static async Task<HttpResponseMessage> InvokeCmdAsync(this ApiController
9199

92100
using (CmdProcess cmd = new CmdProcess(scriptPath, arguments) { OutputEncoding = encoding })
93101
{
94-
int exitCode = await cmd.ExecuteAsync(cancellationToken).ConfigureAwait(false);
95-
string responseString = cmd.GetStandardError();
96-
HttpStatusCode httpStatusCode;
97-
98-
if (exitCode == 0 && string.IsNullOrEmpty(responseString))
102+
try
99103
{
100-
responseString = cmd.GetStandardOutput();
101-
httpStatusCode = string.IsNullOrEmpty(responseString) ? HttpStatusCode.NoContent : HttpStatusCode.OK;
104+
int exitCode = await cmd.ExecuteAsync(cancellationToken).ConfigureAwait(false);
105+
string responseString = cmd.GetStandardError();
106+
HttpStatusCode httpStatusCode;
107+
108+
if (exitCode == 0 && string.IsNullOrEmpty(responseString))
109+
{
110+
responseString = cmd.GetStandardOutput();
111+
httpStatusCode = string.IsNullOrEmpty(responseString) ? HttpStatusCode.NoContent : HttpStatusCode.OK;
112+
}
113+
else
114+
httpStatusCode = HttpStatusCode.InternalServerError;
115+
116+
StringContent responseContent = new StringContent(responseString, encoding, contentNegotiator.NegotiatedMediaType.MediaType);
117+
responseContent.Headers.Add("Exit-Code", exitCode.ToString());
118+
119+
return new HttpResponseMessage(httpStatusCode) { Content = responseContent };
120+
}
121+
catch (Win32Exception e)
122+
{
123+
switch (e.NativeErrorCode)
124+
{
125+
case 2: // ERROR_FILE_NOT_FOUND
126+
case 267: // ERROR_DIRECTORY
127+
return new HttpResponseMessage(HttpStatusCode.NotFound);
128+
default:
129+
throw;
130+
}
102131
}
103-
else
104-
httpStatusCode = HttpStatusCode.InternalServerError;
105-
106-
StringContent responseContent = new StringContent(responseString, encoding, contentNegotiator.NegotiatedMediaType.MediaType);
107-
responseContent.Headers.Add("Exit-Code", exitCode.ToString());
108-
109-
return new HttpResponseMessage(httpStatusCode) { Content = responseContent };
110132
}
111133
}
112134

src/DataBooster.PSWebApi/PSControllerExtensions.cmd.cs

Lines changed: 28 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
using System.Web.Http;
99
using System.Threading;
1010
using System.Collections.Generic;
11+
using System.ComponentModel;
1112
using Newtonsoft.Json.Linq;
1213

1314
namespace DataBooster.PSWebApi
@@ -68,22 +69,36 @@ public static HttpResponseMessage InvokeCmd(this ApiController apiController, st
6869

6970
using (CmdProcess cmd = new CmdProcess(scriptPath, arguments) { OutputEncoding = encoding })
7071
{
71-
int exitCode = cmd.Execute(timeoutSeconds);
72-
string responseString = cmd.GetStandardError();
73-
HttpStatusCode httpStatusCode;
74-
75-
if (exitCode == 0 && string.IsNullOrEmpty(responseString))
72+
try
7673
{
77-
responseString = cmd.GetStandardOutput();
78-
httpStatusCode = string.IsNullOrEmpty(responseString) ? HttpStatusCode.NoContent : HttpStatusCode.OK;
79-
}
80-
else
81-
httpStatusCode = HttpStatusCode.InternalServerError;
74+
int exitCode = cmd.Execute(timeoutSeconds);
75+
string responseString = cmd.GetStandardError();
76+
HttpStatusCode httpStatusCode;
77+
78+
if (exitCode == 0 && string.IsNullOrEmpty(responseString))
79+
{
80+
responseString = cmd.GetStandardOutput();
81+
httpStatusCode = string.IsNullOrEmpty(responseString) ? HttpStatusCode.NoContent : HttpStatusCode.OK;
82+
}
83+
else
84+
httpStatusCode = HttpStatusCode.InternalServerError;
8285

83-
StringContent responseContent = new StringContent(responseString, encoding, contentNegotiator.NegotiatedMediaType.MediaType);
84-
responseContent.Headers.Add("Exit-Code", exitCode.ToString());
86+
StringContent responseContent = new StringContent(responseString, encoding, contentNegotiator.NegotiatedMediaType.MediaType);
87+
responseContent.Headers.Add("Exit-Code", exitCode.ToString());
8588

86-
return new HttpResponseMessage(httpStatusCode) { Content = responseContent };
89+
return new HttpResponseMessage(httpStatusCode) { Content = responseContent };
90+
}
91+
catch (Win32Exception e)
92+
{
93+
switch (e.NativeErrorCode)
94+
{
95+
case 2: // ERROR_FILE_NOT_FOUND
96+
case 267: // ERROR_DIRECTORY
97+
return new HttpResponseMessage(HttpStatusCode.NotFound);
98+
default:
99+
throw;
100+
}
101+
}
87102
}
88103
}
89104
}

src/DataBooster.PSWebApi/PSControllerExtensions.cs

Lines changed: 32 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -71,15 +71,22 @@ public static HttpResponseMessage InvokePowerShell(this ApiController apiControl
7171
if (!string.IsNullOrWhiteSpace(converter.ConversionCmdlet))
7272
ps.AddCommand(converter.ConversionCmdlet, true).Commands.AddParameters(converter.CmdletParameters);
7373

74-
string stringResult = GetPsResult(ps.Invoke(), encoding);
74+
try
75+
{
76+
string stringResult = GetPsResult(ps.Invoke(), encoding);
7577

76-
ps.CheckErrors();
78+
ps.CheckErrors();
7779

78-
StringContent responseContent = new StringContent(stringResult, encoding, contentNegotiator.NegotiatedMediaType.MediaType);
80+
StringContent responseContent = new StringContent(stringResult, encoding, contentNegotiator.NegotiatedMediaType.MediaType);
7981

80-
responseContent.Headers.SetContentHeader(ps.Streams);
82+
responseContent.Headers.SetContentHeader(ps.Streams);
8183

82-
return new HttpResponseMessage(string.IsNullOrEmpty(stringResult) ? HttpStatusCode.NoContent : HttpStatusCode.OK) { Content = responseContent };
84+
return new HttpResponseMessage(string.IsNullOrEmpty(stringResult) ? HttpStatusCode.NoContent : HttpStatusCode.OK) { Content = responseContent };
85+
}
86+
catch (CommandNotFoundException)
87+
{
88+
return new HttpResponseMessage(HttpStatusCode.NotFound);
89+
}
8390
}
8491
}
8592

@@ -144,10 +151,17 @@ private static string GetOneResult(PSObject psObject, Encoding encoding)
144151
if (errors != null && errors.Count > 0)
145152
{
146153
if (errors.Count == 1)
147-
throw errors[0].Exception;
154+
throw RestoreCommandNotFoundException(errors[0]);
148155
else
149-
throw new AggregateException(string.Join(Environment.NewLine, errors.Select(e => e.Exception.Message)),
150-
errors.Select(e => e.Exception));
156+
{
157+
List<Exception> innerExceptions = errors.Select(e => RestoreCommandNotFoundException(e)).ToList();
158+
CommandNotFoundException notFoundException = innerExceptions.OfType<CommandNotFoundException>().FirstOrDefault();
159+
160+
if (notFoundException != null)
161+
throw notFoundException;
162+
else
163+
throw new AggregateException(string.Join(Environment.NewLine, errors.Select(e => e.Exception.Message)), innerExceptions);
164+
}
151165
}
152166

153167
if (ps.HadErrors)
@@ -157,6 +171,16 @@ private static string GetOneResult(PSObject psObject, Encoding encoding)
157171
}
158172
}
159173

174+
private static Exception RestoreCommandNotFoundException(ErrorRecord errorRecord)
175+
{
176+
var wrapperException = errorRecord.Exception;
177+
178+
if (wrapperException is ParentContainsErrorRecordException && errorRecord.FullyQualifiedErrorId.Equals("CommandNotFoundException", StringComparison.Ordinal))
179+
return new CommandNotFoundException(wrapperException.Message, wrapperException.InnerException);
180+
else
181+
return wrapperException;
182+
}
183+
160184
private static void SetContentHeader(this HttpContentHeaders headers, PSDataStreams invokedStatus)
161185
{
162186
if (invokedStatus == null || headers == null)

src/DataBooster.PSWebApi/Properties/AssemblyInfo.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,6 @@
3232
// You can specify all the values or you can default the Build and Revision Numbers
3333
// by using the '*' as shown below:
3434
// [assembly: AssemblyVersion("1.0.*")]
35-
[assembly: AssemblyVersion("1.1.8.0")]
36-
[assembly: AssemblyFileVersion("1.1.8.0")]
37-
[assembly: AssemblyInformationalVersion("1.1.8.0")]
35+
[assembly: AssemblyVersion("1.1.8.1")]
36+
[assembly: AssemblyFileVersion("1.1.8.1")]
37+
[assembly: AssemblyInformationalVersion("1.1.8.1")]

0 commit comments

Comments
 (0)