From 3bdf3cdfaaeb4ffd55e253c010663295c81e036e Mon Sep 17 00:00:00 2001 From: Aayush Pandey Date: Wed, 3 Jun 2026 22:57:06 -0700 Subject: [PATCH 1/2] Improve OpenAPI parsing exception logging --- .../OpenApiDocumentDownloadService.cs | 12 ++++- .../OpenApiDocumentDownloadServiceTests.cs | 48 ++++++++++++++++++- 2 files changed, 57 insertions(+), 3 deletions(-) diff --git a/src/Kiota.Builder/OpenApiDocumentDownloadService.cs b/src/Kiota.Builder/OpenApiDocumentDownloadService.cs index 62c3709cc4..cac9b81869 100644 --- a/src/Kiota.Builder/OpenApiDocumentDownloadService.cs +++ b/src/Kiota.Builder/OpenApiDocumentDownloadService.cs @@ -137,7 +137,17 @@ ex is SecurityException || { // couldn't parse the URL, it's probably a local file } - var readResult = await OpenApiDocument.LoadAsync(input, settings: settings, cancellationToken: cancellationToken).ConfigureAwait(false); + + ReadResult readResult; + try + { + readResult = await OpenApiDocument.LoadAsync(input, settings: settings, cancellationToken: cancellationToken).ConfigureAwait(false); + } + catch (Exception ex) + { + Logger.LogWarning(ex, "Error parsing specification {Path}", config.OpenAPIFilePath); + throw; + } stopwatch.Stop(); if (generatingMode && readResult.Diagnostic?.Warnings is { Count: > 0 }) foreach (var warning in readResult.Diagnostic.Warnings) diff --git a/tests/Kiota.Builder.Tests/OpenApiDocumentDownloadServiceTests.cs b/tests/Kiota.Builder.Tests/OpenApiDocumentDownloadServiceTests.cs index 18ccc0b7c8..6e39a967b0 100644 --- a/tests/Kiota.Builder.Tests/OpenApiDocumentDownloadServiceTests.cs +++ b/tests/Kiota.Builder.Tests/OpenApiDocumentDownloadServiceTests.cs @@ -30,7 +30,6 @@ public sealed class OpenApiDocumentDownloadServiceTests : IDisposable schema: type: object"; - public void Dispose() { _httpClient.Dispose(); @@ -78,6 +77,51 @@ public async Task GetDocumentFromStreamAsyncTest_No_IncludeKiotaValidationRulesI Assert.Empty(logEntryForNoServerRule); } + [Fact] + public async Task GetDocumentFromStreamAsync_LogsSpecificationPathWhenParsingThrows() + { + const string brokenDocument = """ +{ + "openapi": "3.0.1", + "info": { + "title": "Repro API", + "version": "1.0.0" + }, + "paths": {}, + "components": { + "schemas": { + "ItemStatus": { + "type": "string", + "enum": [ + "Active", + "Archived" + ], + "x-ms-enum-flags": [] + } + } + } +} +"""; + + var generationConfig = new GenerationConfiguration + { + OpenAPIFilePath = "repro-broken.json" + }; + var fakeLogger = new FakeLogger(); + + using var inputDocumentStream = CreateMemoryStreamFromString(brokenDocument); + var documentDownloadService = new OpenApiDocumentDownloadService(_httpClient, fakeLogger); + + await Assert.ThrowsAsync(() => + documentDownloadService.GetDocumentFromStreamAsync(inputDocumentStream, generationConfig, cancellationToken: TestContext.Current.CancellationToken)); + + var parsingLogEntry = fakeLogger.LogEntries + .Where(l => l.message.Contains("Error parsing specification", StringComparison.OrdinalIgnoreCase)); + + var logEntry = Assert.Single(parsingLogEntry); + Assert.Contains("repro-broken.json", logEntry.message, StringComparison.OrdinalIgnoreCase); + } + [Fact] public async Task GetDocumentFromStreamAsyncTest_Default_IncludeKiotaValidationRulesInConfig() { @@ -107,4 +151,4 @@ private static Stream CreateMemoryStreamFromString(string s) stream.Position = 0; return stream; } -} +} \ No newline at end of file From 95b6d0d5be90314e8dafaa17240b72c6f41c43a9 Mon Sep 17 00:00:00 2001 From: Aayush Pandey Date: Thu, 4 Jun 2026 21:15:28 -0700 Subject: [PATCH 2/2] Use critical logger message for OpenAPI parse failures --- src/Kiota.Builder/OpenApiDocumentDownloadService.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/Kiota.Builder/OpenApiDocumentDownloadService.cs b/src/Kiota.Builder/OpenApiDocumentDownloadService.cs index cac9b81869..1f7ed0a752 100644 --- a/src/Kiota.Builder/OpenApiDocumentDownloadService.cs +++ b/src/Kiota.Builder/OpenApiDocumentDownloadService.cs @@ -145,7 +145,7 @@ ex is SecurityException || } catch (Exception ex) { - Logger.LogWarning(ex, "Error parsing specification {Path}", config.OpenAPIFilePath); + LogOpenApiParsingCriticalError(ex, config.OpenAPIFilePath); throw; } stopwatch.Stop(); @@ -198,6 +198,9 @@ ex is SecurityException || [LoggerMessage(Level = LogLevel.Error, Message = "OpenAPI error: {Pointer} - {Message}")] private partial void LogOpenApiError(string? pointer, string message); + [LoggerMessage(Level = LogLevel.Critical, Message = "Error parsing specification {Path}")] + private partial void LogOpenApiParsingCriticalError(Exception exception, string path); + [LoggerMessage(Level = LogLevel.Trace, Message = "{Timestamp}ms: Parsed OpenAPI successfully. {Count} paths found.")] private partial void LogParsedOpenApiSuccessfully(long timestamp, int count); }