Skip to content

Commit 04ee5fc

Browse files
authored
Merge pull request #33 from darkpatternsdigital/bugfix/improve-invalid-schema-diagnostics
Improve invalid schema diagnostics
2 parents a8c9d8d + 4a16041 commit 04ee5fc

7 files changed

Lines changed: 52 additions & 14 deletions

File tree

Directory.Build.props

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232
<OpenApiAbstractionsVersion>0.3.0</OpenApiAbstractionsVersion>
3333
<OpenApiJsonExtensionsVersion>0.18.0</OpenApiJsonExtensionsVersion>
3434
<OpenApiLoadersVersion>0.2.0</OpenApiLoadersVersion>
35-
<OpenApiCSharpVersion>0.25.2</OpenApiCSharpVersion>
35+
<OpenApiCSharpVersion>0.25.3</OpenApiCSharpVersion>
3636
<OpenApiTypeScriptClientVersion>0.12.2</OpenApiTypeScriptClientVersion>
3737
<OpenApiTypeScriptRxjsClientVersion>0.9.0</OpenApiTypeScriptRxjsClientVersion>
3838
<OpenApiTypeScriptMswVersion>0.9.0</OpenApiTypeScriptMswVersion>

generators/csharp/OpenApiCodegen.CSharp.Base/Client/OperationVisitor.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ public override void Visit(OpenApiOperation operation, string httpMethod, Argume
9595
public override void Visit(OpenApiParameter param, Argument argument)
9696
{
9797
var info = param.Schema?.ResolveSchemaInfo();
98-
var dataType = inlineSchemas.ToInlineDataType(param.Schema) ?? CSharpInlineSchemas.AnyObject;
98+
var dataType = inlineSchemas.SafeToInlineDataType(param.Schema, argument.Diagnostic) ?? CSharpInlineSchemas.AnyObject;
9999
argument.Builder?.SharedParameters.Add(new OperationParameter(
100100
RawName: param.Name,
101101
ParamName: CSharpNaming.ToParameterName(param.Name, options.ReservedIdentifiers()),
@@ -133,7 +133,7 @@ public override void Visit(OpenApiResponse response, int? statusCode, Argument a
133133
Description: response.Description,
134134
Content: (from entry in (from c in content ?? Enumerable.Empty<KeyValuePair<string, OpenApiMediaTypeObject>>()
135135
select (c.Key, c.Value.Schema)).DefaultIfEmpty((Key: "", Schema: null))
136-
let dataType = entry.Schema != null ? inlineSchemas.ToInlineDataType(entry.Schema) : null
136+
let dataType = entry.Schema != null ? inlineSchemas.SafeToInlineDataType(entry.Schema, argument.Diagnostic) : null
137137
where entry.Key != "application/xml" // exclude xml, since we don't support it
138138
select new OperationResponseContentOption(
139139
MediaType: entry.Key,
@@ -143,7 +143,7 @@ public override void Visit(OpenApiResponse response, int? statusCode, Argument a
143143
Headers: (from entry in response.Headers
144144
let required = entry.Required
145145
let info = entry.Schema?.ResolveSchemaInfo()
146-
let dataType = inlineSchemas.ToInlineDataType(entry.Schema)
146+
let dataType = inlineSchemas.SafeToInlineDataType(entry.Schema, argument.Diagnostic)
147147
select new OperationResponseHeader(
148148
RawName: entry.Name,
149149
ParamName: CSharpNaming.ToParameterName("header " + entry.Name, options.ReservedIdentifiers()),
@@ -183,7 +183,7 @@ IEnumerable<OperationParameter> GetFormParams() =>
183183
from param in mediaTypeSchemaInfo?.TryGetAnnotation<PropertiesKeyword>()?.Properties
184184
let required = mediaTypeSchemaInfo?.TryGetAnnotation<RequiredKeyword>()?.RequiredProperties.Contains(param.Key) ?? false
185185
let info = param.Value?.ResolveSchemaInfo()
186-
let dataType = inlineSchemas.ToInlineDataType(param.Value)
186+
let dataType = inlineSchemas.SafeToInlineDataType(param.Value, argument.Diagnostic)
187187
select new OperationParameter(
188188
RawName: param.Key,
189189
ParamName: CSharpNaming.ToParameterName(param.Key, options.ReservedIdentifiers()),
@@ -207,7 +207,7 @@ IEnumerable<OperationParameter> GetFormParams() =>
207207
IEnumerable<OperationParameter> GetStandardParams() =>
208208
from ct in new[] { mediaType }
209209
let info = ct.Schema?.ResolveSchemaInfo()
210-
let dataType = inlineSchemas.ToInlineDataType(ct.Schema)
210+
let dataType = inlineSchemas.SafeToInlineDataType(ct.Schema, argument.Diagnostic)
211211
select new OperationParameter(
212212
RawName: null,
213213
ParamName: CSharpNaming.ToParameterName(argument.Builder?.Operation.OperationId + " body", options.ReservedIdentifiers()),

generators/csharp/OpenApiCodegen.CSharp.Base/MvcServer/CSharpControllerTransformer.cs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
using DarkPatterns.OpenApiCodegen.Handlebars;
77
using DarkPatterns.OpenApi.CSharp;
88
using DarkPatterns.OpenApiCodegen.CSharp.MvcServer.Templates;
9+
using DarkPatterns.Json.Diagnostics;
910

1011
namespace DarkPatterns.OpenApiCodegen.CSharp.MvcServer;
1112

@@ -21,7 +22,16 @@ public SourceEntry TransformController(string groupName, OperationGroupData grou
2122
var resultOperations = new List<ControllerOperation>();
2223
var visitor = new ControllerOperationVisitor(settings.SchemaRegistry, options, controllerClassName: className);
2324
foreach (var (operation, method, path) in operations)
24-
visitor.Visit(operation, method, new ControllerOperationVisitor.Argument(diagnostic, resultOperations.Add, CurrentPath: path));
25+
{
26+
try
27+
{
28+
visitor.Visit(operation, method, new ControllerOperationVisitor.Argument(diagnostic, resultOperations.Add, CurrentPath: path));
29+
}
30+
catch (Exception ex)
31+
{
32+
diagnostic.Diagnostics.AddRange(ex.ToDiagnostics(settings.SchemaRegistry.DocumentRegistry, operation.Metadata));
33+
}
34+
}
2535

2636
var template = new Templates.ControllerTemplate(
2737
Header: settings.Header(document.Id),

lib/OpenApi.CSharp/CSharpInlineSchemas.cs

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,33 @@ public class CSharpInlineSchemas(CSharpSchemaOptions options, DocumentRegistry d
2222
public CSharpInlineDefinition? ToInlineDataType(JsonSchema? schema)
2323
{
2424
if (schema == null) return null;
25-
return ToInlineDataType(schema.ResolveSchemaInfo());
25+
try
26+
{
27+
return ToInlineDataType(schema.ResolveSchemaInfo());
28+
}
29+
catch (Exception ex)
30+
{
31+
throw new MultipleDiagnosticException([
32+
.. ex.ToDiagnostics(documentRegistry, schema.Metadata),
33+
]);
34+
}
35+
}
36+
37+
[return: System.Diagnostics.CodeAnalysis.NotNullIfNotNull(nameof(schema))]
38+
public CSharpInlineDefinition? SafeToInlineDataType(JsonSchema? schema, OpenApiTransformDiagnostic diagnostic)
39+
{
40+
if (schema == null) return null;
41+
try
42+
{
43+
return ToInlineDataType(schema.ResolveSchemaInfo());
44+
}
45+
catch (Exception ex)
46+
{
47+
diagnostic.Diagnostics.AddRange([
48+
.. ex.ToDiagnostics(documentRegistry, schema.Metadata),
49+
]);
50+
return CSharpInlineSchemas.AnyObject;
51+
}
2652
}
2753

2854
[return: NotNullIfNotNull(nameof(schema))]
@@ -226,4 +252,4 @@ _ when int.TryParse(statusCode, out var numeric) && HttpStatusCodes.StatusCodeNa
226252
};
227253
}
228254
}
229-
}
255+
}

lib/OpenApi.CSharp/CSharpSchemaSourceProvider.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ private Templates.ObjectModel ToObjectModel(string className, JsonSchemaInfo sch
103103

104104
Templates.ModelVar[] vars = (from entry in properties
105105
let req = required.Contains(entry.Key)
106-
let dataType = inlineSchemas.ToInlineDataType(entry.Value.EffectiveSchema)
106+
let dataType = inlineSchemas.SafeToInlineDataType(entry.Value.EffectiveSchema, diagnostic)
107107
let resolved = objectModel.LegacyOptionalBehavior && !req ? dataType.MakeNullable() : dataType
108108
select new Templates.ModelVar(
109109
BaseName: entry.Key,

lib/OpenApiCodegen.Server.Mvc.Test/ComprehensiveTransformsShould.cs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -98,8 +98,10 @@ public void Reports_diagnostics_for_bad_2_yaml()
9898
{
9999
Assert.IsType<UnableToCreateInlineSchemaDiagnostic>(diag);
100100
Assert.Equal("proj://embedded/bad.2.yaml", diag.Location.RetrievalUri.OriginalString);
101-
Assert.Equal(16, diag.Location.Range?.Start.Line);
102-
Assert.Equal(17, diag.Location.Range?.Start.Column);
101+
Assert.Equal(18, diag.Location.Range?.Start.Line);
102+
Assert.Equal(25, diag.Location.Range?.Start.Column);
103+
Assert.Equal(18, diag.Location.Range?.End.Line);
104+
Assert.Equal(55, diag.Location.Range?.End.Column);
103105
}
104106
);
105107
}

lib/TestApp.Bad/OpenApiCodegen.Server.Mvc.TestApp.Bad.csproj

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@
1111
</PropertyGroup>
1212

1313
<ItemGroup>
14-
<!-- <OpenApiSchemaMvcServer Include="$(SolutionRoot)schemas\bad.yaml" Link="Bad\bad.yaml" PathPrefix="/bad" SchemaId="proj://darkpatterns-openapi/bad.yaml" /> -->
15-
<OpenApiSchemaMvcServer Include="$(SolutionRoot)schemas\bad.2.yaml" Link="Bad\bad.2.yaml" PathPrefix="/bad" SchemaId="proj://darkpatterns-openapi/bad.2.yaml" />
14+
<OpenApiSchemaMvcServer Include="$(SolutionRoot)schemas\bad.yaml" Link="Bad\bad.yaml" PathPrefix="/bad" Namespace="DarkPatterns.OpenApiCodegen.Server.Mvc.TestApp.Bad.Bad" SchemaId="proj://darkpatterns-openapi/bad.yaml" />
15+
<OpenApiSchemaMvcServer Include="$(SolutionRoot)schemas\bad.2.yaml" Link="Bad\bad.2.yaml" PathPrefix="/bad2" Namespace="DarkPatterns.OpenApiCodegen.Server.Mvc.TestApp.Bad.Bad2" SchemaId="proj://darkpatterns-openapi/bad.2.yaml" />
1616

1717
<Compile Remove="generated/**/*" />
1818
<Clean Include="generated/**/*" />

0 commit comments

Comments
 (0)