Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 40 additions & 0 deletions src/readme.graph.md
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,27 @@ directive:
}
}
}
# Add Microsoft Graph error properties to InnerError.
- from: 'openapi-document'
where: $.components.schemas['microsoft.graph.ODataErrors.InnerError']
transform: >-
return {
"type": "object",
"properties": {
"date" : {
"type" : 'string'
},
"request-id" : {
"type" : 'string'
},
"client-request-id" : {
"type" : 'string'
}
},
"additionalProperties": {
"type" : "object"
}
}
# Mark '@odata.id' as required properties for /$ref.
- from: 'openapi-document'
where: $.components.schemas.ReferenceCreate
Expand Down Expand Up @@ -399,6 +420,10 @@ directive:
}
}

// Format error details.
let errorDetailsRegex = /(ErrorDetails\s*=\s*)(new.*ErrorDetails\(message\).*)/gmi
$ = $.replace(errorDetailsRegex, '$1await this.GetErrorDetailsAsync((await response)?.Error, responseMessage)');

return $;
}

Expand Down Expand Up @@ -547,6 +572,21 @@ directive:
return $;
}

# Modify generated JsonObject class.
- from: source-file-csharp
where: $
transform: >
if (!$documentPath.match(/generated%2Fruntime%2FNodes%2FJsonObject.cs/gm))
{
return $;
} else {
// Make JsonObject's items dictionary case insensitive.
let dictionaryInitRegex = /(\s*=\s*new\s*Dictionary<string,\s*JsonNode>\()(\);)/gm
$ = $.replace(dictionaryInitRegex, '$1StringComparer.InvariantCultureIgnoreCase$2');

return $;
}

# Modify API class.
- from: source-file-csharp
where: $
Expand Down
31 changes: 25 additions & 6 deletions tools/Custom/HttpMessageLogFormatter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

namespace NamespacePrefixPlaceholder.PowerShell
{
using NamespacePrefixPlaceholder.PowerShell.Models;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
Expand Down Expand Up @@ -63,9 +64,9 @@ public static async Task<string> GetHttpRequestLogAsync(HttpRequestMessage reque

StringBuilder stringBuilder = new StringBuilder();
stringBuilder.AppendLine($"============================ HTTP REQUEST ============================{Environment.NewLine}");
stringBuilder.AppendLine($"HTTP Method:{Environment.NewLine}{requestClone.Method.ToString()}{Environment.NewLine}");
stringBuilder.AppendLine($"Absolute Uri:{Environment.NewLine}{requestClone.RequestUri.ToString()}{Environment.NewLine}");
stringBuilder.AppendLine($"Headers:{Environment.NewLine}{HeadersToString(ConvertHttpHeadersToCollection(requestClone.Headers))}{Environment.NewLine}");
stringBuilder.AppendLine($"HTTP Method:{Environment.NewLine}{requestClone.Method}{Environment.NewLine}");
stringBuilder.AppendLine($"Absolute Uri:{Environment.NewLine}{requestClone.RequestUri}{Environment.NewLine}");
stringBuilder.AppendLine($"Headers:{Environment.NewLine}{HeadersToString(requestClone.Headers)}{Environment.NewLine}");
stringBuilder.AppendLine($"Body:{Environment.NewLine}{SanitizeBody(body)}{Environment.NewLine}");
return stringBuilder.ToString();
}
Expand All @@ -84,12 +85,30 @@ public static async Task<string> GetHttpResponseLogAsync(HttpResponseMessage res
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.AppendLine($"============================ HTTP RESPONSE ============================{Environment.NewLine}");
stringBuilder.AppendLine($"Status Code:{Environment.NewLine}{response.StatusCode}{Environment.NewLine}");
stringBuilder.AppendLine($"Headers:{Environment.NewLine}{HeadersToString(ConvertHttpHeadersToCollection(response.Headers))}{Environment.NewLine}");
stringBuilder.AppendLine($"Headers:{Environment.NewLine}{HeadersToString(response.Headers)}{Environment.NewLine}");
stringBuilder.AppendLine($"Body:{Environment.NewLine}{SanitizeBody(body)}{Environment.NewLine}");
return stringBuilder.ToString();
}

private static Regex regexPattern = new Regex("(\\s*\"access_token\"\\s*:\\s*)\"[^\"]+\"", RegexOptions.Compiled);
public static async Task<string> GetErrorLogAsync(HttpResponseMessage response, IMicrosoftGraphODataErrorsMainError odataError)
{
if (response == null) return string.Empty;

StringBuilder stringBuilder = new StringBuilder();
stringBuilder.AppendLine($"{odataError?.Message}{Environment.NewLine}");
stringBuilder.AppendLine($"Status: {((int)response.StatusCode)} ({response.StatusCode})");
stringBuilder.AppendLine($"ErrorCode: {odataError?.Code}");
stringBuilder.AppendLine($"Date: {odataError?.Innererror?.Date}{Environment.NewLine}");
stringBuilder.AppendLine($"Headers:{Environment.NewLine}{HeadersToString(response.Headers)}{Environment.NewLine}");
return stringBuilder.ToString();
}

internal static string HeadersToString(HttpHeaders headers)
{
return HeadersToString(ConvertHttpHeadersToCollection(headers));
}

private static readonly Regex regexPattern = new Regex("(\\s*\"access_token\"\\s*:\\s*)\"[^\"]+\"", RegexOptions.Compiled);
private static object SanitizeBody(string body)
{
IList<Regex> regexList = new List<Regex>();
Expand All @@ -110,7 +129,7 @@ private static IDictionary<string, IEnumerable<string>> ConvertHttpHeadersToColl
return headers.ToDictionary(a => a.Key, a => a.Value);
}

private static object HeadersToString(IDictionary<string, IEnumerable<string>> headers)
private static string HeadersToString(IDictionary<string, IEnumerable<string>> headers)
{
StringBuilder stringBuilder = headers.Aggregate(new StringBuilder(),
(sb, kvp) => sb.AppendLine(string.Format("{0,-30}: {1}", kvp.Key, String.Join(",", kvp.Value.ToArray()))));
Expand Down
12 changes: 12 additions & 0 deletions tools/Custom/PSCmdletExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ namespace NamespacePrefixPlaceholder.PowerShell
{
using Microsoft.Graph.PowerShell.Authentication;
using Microsoft.Graph.PowerShell.Authentication.Common;
using NamespacePrefixPlaceholder.PowerShell.Models;
using System;
using System.Collections.ObjectModel;
using System.IO;
Expand Down Expand Up @@ -104,6 +105,17 @@ internal static void WriteToFile(this PSCmdlet cmdlet, HttpResponseMessage respo
cmdlet.WriteToStream(inputStream, fileProvider.Stream, downloadUrl, cancellationToken);
}
}

internal static async Task<ErrorDetails> GetErrorDetailsAsync(this PSCmdlet cmdlet, IMicrosoftGraphODataErrorsMainError odataError, HttpResponseMessage response)
{
var serviceErrorDoc = "https://learn.microsoft.com/graph/errors";
var recommendedAction = $"See service error codes: {serviceErrorDoc}";
var errorDetailsMessage = await HttpMessageLogFormatter.GetErrorLogAsync(response, odataError);
return new ErrorDetails(errorDetailsMessage)
{
RecommendedAction = recommendedAction
};
}

/// <summary>
/// Writes an input stream to an output stream.
Expand Down