RicoSuter / NSwag

The Swagger/OpenAPI toolchain for .NET, ASP.NET Core and TypeScript.
http://NSwag.org
MIT License
6.61k stars 1.22k forks source link

Bug: impossible to generate exception classes for non-first client #4890

Closed bkoelman closed 3 days ago

bkoelman commented 1 month ago

When a project contains multiple <OpenApiReference> entries, the ApiException class is only generated for the first entry. While this is a nice default, since v14 it has become impossible to generate exception classes for all entries (they live in separate namespaces).

The problematic line is in NSwag.ApiDescription.Client.targets:

<Command Condition="!%(FirstForGenerator) OR (%(NSwagGenerateExceptionClasses) != '' AND !%(NSwagGenerateExceptionClasses))">%(Command) /GenerateExceptionClasses:false</Command>

which always adds /GenerateExceptionClasses:false for the non-first entry, ignoring the configured value of NSwagGenerateExceptionClasses in <OpenApiReference>.

When trying to work around it by adding the argument explicitly using:

<Options>/GenerateExceptionClasses:true</Options>

the build fails because the /GenerateExceptionClasses parameter is now specified multiple times (which makes NConsole fail).

GenerateExceptionClassesDemo.zip contains a minimal repro. It fails to build the generated QueryStringsClient file (second entry in csproj), because it doesn't declare the ApiException class while referencing it.

To fix this, the problematic line should be replaced with:

<Command Condition="!%(FirstForGenerator) AND ('%(NSwagGenerateExceptionClasses)' == '')">%(Command) /generateExceptionClasses:false</Command>
<Command Condition="'%(NSwagGenerateExceptionClasses)' != ''">%(Command) /generateExceptionClasses:%(NSwagGenerateExceptionClasses)</Command>

The fix only adds /generateExceptionClasses:false for non-first entries that aren't configured. In all other cases, it takes the configured value, similar to all the other NSwag* properties. When /generateExceptionClasses is omitted, it defaults to true.

The same fix should be applied for NSwagGenerateResponseClasses, which works similarly.

Additionally, generation of the JsonInheritanceConverter, JsonInheritanceConverterAttribute, and JsonInheritanceAttribute classes could benefit from the same fix, but there's no NSwag* property to control whether they are generated.