| | 1 | | using System.Management.Automation; |
| | 2 | | using System.Text; |
| | 3 | | using Serilog; |
| | 4 | |
|
| | 5 | | namespace Kestrun.Utilities; |
| | 6 | |
|
| | 7 | | /// <summary> |
| | 8 | | /// Utilities for formatting PowerShell error streams into HTTP responses. |
| | 9 | | /// </summary> |
| | 10 | | public static class BuildError |
| | 11 | | { |
| | 12 | | /// <summary> |
| | 13 | | /// Convert the current PowerShell error streams to a plain-text <see cref="IResult"/>. |
| | 14 | | /// </summary> |
| 1 | 15 | | public static IResult Result(PowerShell ps) => Results.Text(content: Text(ps), statusCode: 500, contentType: "text/p |
| | 16 | |
|
| | 17 | |
|
| | 18 | |
|
| | 19 | | /// <summary> |
| | 20 | | /// Collate all PowerShell streams (error, verbose, warning, etc.) into a single string. |
| | 21 | | /// </summary> |
| | 22 | | public static string Text(PowerShell ps) |
| | 23 | | { |
| 6 | 24 | | ArgumentNullException.ThrowIfNull(ps); |
| | 25 | |
|
| 12 | 26 | | var errors = ps.Streams.Error.Select(e => e.ToString()); |
| 6 | 27 | | var verbose = ps.Streams.Verbose.Select(v => v.ToString()); |
| 6 | 28 | | var warnings = ps.Streams.Warning.Select(w => w.ToString()); |
| 6 | 29 | | var debug = ps.Streams.Debug.Select(d => d.ToString()); |
| 7 | 30 | | var info = ps.Streams.Information.Select(i => i.ToString()); |
| | 31 | | // Format the output |
| | 32 | | // 500 + text body |
| | 33 | |
|
| 6 | 34 | | var sb = new StringBuilder(); |
| | 35 | |
|
| | 36 | | void append(string emoji, IEnumerable<string> lines) |
| | 37 | | { |
| 30 | 38 | | if (!lines.Any()) |
| | 39 | | { |
| 23 | 40 | | return; |
| | 41 | | } |
| | 42 | |
|
| 7 | 43 | | _ = sb.AppendLine($"{emoji}[{emoji switch |
| 7 | 44 | | { |
| 6 | 45 | | "❌" => "Error", |
| 0 | 46 | | "💬" => "Verbose", |
| 0 | 47 | | "⚠️" => "Warning", |
| 0 | 48 | | "🐞" => "Debug", |
| 1 | 49 | | _ => "Info" |
| 7 | 50 | | }}]"); |
| 28 | 51 | | foreach (var l in lines) |
| | 52 | | { |
| 7 | 53 | | _ = sb.AppendLine($"\t{l}"); |
| | 54 | | } |
| 7 | 55 | | } |
| | 56 | |
|
| 6 | 57 | | append("❌", errors); |
| 6 | 58 | | append("💬", verbose); |
| 6 | 59 | | append("⚠️", warnings); |
| 6 | 60 | | append("🐞", debug); |
| 6 | 61 | | append("ℹ️", info); |
| | 62 | |
|
| 6 | 63 | | var msg = sb.ToString(); |
| 6 | 64 | | Log.Information(msg); |
| | 65 | |
|
| | 66 | |
|
| 6 | 67 | | return msg; |
| | 68 | | } |
| | 69 | |
|
| | 70 | | // Helper that writes the error to the response stream |
| | 71 | | /// <summary> |
| | 72 | | /// Write the formatted PowerShell errors directly to the HTTP response. |
| | 73 | | /// </summary> |
| | 74 | | public static Task ResponseAsync(HttpContext context, PowerShell ps) |
| | 75 | | { |
| 3 | 76 | | var errText = Text(ps); |
| 3 | 77 | | context.Response.StatusCode = 500; |
| 3 | 78 | | context.Response.ContentType = "text/plain; charset=utf-8"; |
| 3 | 79 | | return context.Response.WriteAsync(errText); |
| | 80 | | } |
| | 81 | | } |