From 5668c35f49c662715645ebeaa4395bb97e913da2 Mon Sep 17 00:00:00 2001 From: "zach.dow" Date: Fri, 26 Jun 2020 14:10:12 -0700 Subject: [PATCH 1/3] JSON.parse will throw on any input that isn't a string. Interceptors may change the data to return as a valid JS object/array/etc. While not perfect, it will simply return the object it has in the case that it throws an error. Also adds in the jsonParse function call for HandleReferences in case an override wants to be provided though code. --- .../AxiosTests.cs | 56 +++++++++++++++++++ ...nt.ProcessResponse.HandleStatusCode.liquid | 5 +- 2 files changed, 60 insertions(+), 1 deletion(-) diff --git a/src/NSwag.CodeGeneration.TypeScript.Tests/AxiosTests.cs b/src/NSwag.CodeGeneration.TypeScript.Tests/AxiosTests.cs index 642fcd4739..704bd8b0b1 100644 --- a/src/NSwag.CodeGeneration.TypeScript.Tests/AxiosTests.cs +++ b/src/NSwag.CodeGeneration.TypeScript.Tests/AxiosTests.cs @@ -2,6 +2,8 @@ using Xunit; using NSwag.Generation.WebApi; using Microsoft.AspNetCore.Mvc; +using System; +using System.Globalization; namespace NSwag.CodeGeneration.TypeScript.Tests { @@ -18,6 +20,12 @@ public class DiscussionController : Controller public void AddMessage([FromBody]Foo message) { } + + [HttpGet] + public Foo GetMessage([FromBody] int id) + { + throw new NotImplementedException(); + } } public class UrlEncodedRequestConsumingController: Controller @@ -128,5 +136,53 @@ public async Task Add_cancel_token_to_every_call() //// Assert Assert.Contains("cancelToken?: CancelToken | undefined", code); } + + [Fact] + public async Task When_typestyle_is_interface_without_handlereferences_will_have_parse_trycatch() + { + //// Arrange + var generator = new WebApiOpenApiDocumentGenerator(new WebApiOpenApiDocumentGeneratorSettings()); + var document = await generator.GenerateForControllerAsync(); + + //// Act + var codeGen = new TypeScriptClientGenerator(document, new TypeScriptClientGeneratorSettings + { + Template = TypeScriptTemplate.Axios, + PromiseType = PromiseType.Promise, + TypeScriptGeneratorSettings = + { + TypeStyle = NJsonSchema.CodeGeneration.TypeScript.TypeScriptTypeStyle.Interface, + HandleReferences = false + } + }); + var code = codeGen.GenerateFile(); + + //// Assert + Assert.Contains("try { resultData200 =", code); + } + + [Fact] + public async Task When_typestyle_is_interface_with_handlereferences_will_have_jsonParse() + { + //// Arrange + var generator = new WebApiOpenApiDocumentGenerator(new WebApiOpenApiDocumentGeneratorSettings()); + var document = await generator.GenerateForControllerAsync(); + + //// Act + var codeGen = new TypeScriptClientGenerator(document, new TypeScriptClientGeneratorSettings + { + Template = TypeScriptTemplate.Axios, + PromiseType = PromiseType.Promise, + TypeScriptGeneratorSettings = + { + TypeStyle = NJsonSchema.CodeGeneration.TypeScript.TypeScriptTypeStyle.Interface, + HandleReferences = true + } + }); + var code = codeGen.GenerateFile(); + + //// Assert + Assert.Contains("jsonParse(", code); + } } } diff --git a/src/NSwag.CodeGeneration.TypeScript/Templates/Client.ProcessResponse.HandleStatusCode.liquid b/src/NSwag.CodeGeneration.TypeScript/Templates/Client.ProcessResponse.HandleStatusCode.liquid index 4942786570..aff26be3b3 100644 --- a/src/NSwag.CodeGeneration.TypeScript/Templates/Client.ProcessResponse.HandleStatusCode.liquid +++ b/src/NSwag.CodeGeneration.TypeScript/Templates/Client.ProcessResponse.HandleStatusCode.liquid @@ -37,8 +37,11 @@ let result{{ response.StatusCode }}: any = null; let resultData{{ response.StatusCode }} = _responseText; {% if response.UseDtoClass -%} {{ response.DataConversionCode }} +{% elseif operation.HandleReferences -%} +resultData{{ response.StatusCode }} = _responseText === "" ? null : <{{ response.Type }}>jsonParse(_responseText, this.jsonParseReviver); {% else -%} -result{{ response.StatusCode }} = JSON.parse(resultData{{ response.StatusCode }}); +try { resultData{{ response.StatusCode }} = (_responseText === "" ? null : <{{ response.Type }}>JSON.parse(_responseText, this.jsonParseReviver)); } +catch(err) { resultData{{ response.StatusCode }} = _responseText; } {% endif -%} {% else -%} {% if response.UseDtoClass or response.IsDateOrDateTime -%} From f0e89545f246cfba4e92b0e42d9cedf9f713049e Mon Sep 17 00:00:00 2001 From: "zach.dow" Date: Mon, 29 Jun 2020 11:14:55 -0700 Subject: [PATCH 2/3] Fixing variable names --- src/NSwag.CodeGeneration.TypeScript.Tests/AxiosTests.cs | 2 +- .../Client.ProcessResponse.HandleStatusCode.liquid | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/NSwag.CodeGeneration.TypeScript.Tests/AxiosTests.cs b/src/NSwag.CodeGeneration.TypeScript.Tests/AxiosTests.cs index 704bd8b0b1..61bab51938 100644 --- a/src/NSwag.CodeGeneration.TypeScript.Tests/AxiosTests.cs +++ b/src/NSwag.CodeGeneration.TypeScript.Tests/AxiosTests.cs @@ -158,7 +158,7 @@ public async Task When_typestyle_is_interface_without_handlereferences_will_have var code = codeGen.GenerateFile(); //// Assert - Assert.Contains("try { resultData200 =", code); + Assert.Contains("try { result200 =", code); } [Fact] diff --git a/src/NSwag.CodeGeneration.TypeScript/Templates/Client.ProcessResponse.HandleStatusCode.liquid b/src/NSwag.CodeGeneration.TypeScript/Templates/Client.ProcessResponse.HandleStatusCode.liquid index aff26be3b3..a60132b97c 100644 --- a/src/NSwag.CodeGeneration.TypeScript/Templates/Client.ProcessResponse.HandleStatusCode.liquid +++ b/src/NSwag.CodeGeneration.TypeScript/Templates/Client.ProcessResponse.HandleStatusCode.liquid @@ -38,14 +38,14 @@ let resultData{{ response.StatusCode }} = _responseText; {% if response.UseDtoClass -%} {{ response.DataConversionCode }} {% elseif operation.HandleReferences -%} -resultData{{ response.StatusCode }} = _responseText === "" ? null : <{{ response.Type }}>jsonParse(_responseText, this.jsonParseReviver); +result{{ response.StatusCode }} = _responseText === "" ? null : <{{ response.Type }}>jsonParse(resultData{{ response.StatusCode }}, this.jsonParseReviver); {% else -%} -try { resultData{{ response.StatusCode }} = (_responseText === "" ? null : <{{ response.Type }}>JSON.parse(_responseText, this.jsonParseReviver)); } -catch(err) { resultData{{ response.StatusCode }} = _responseText; } +try { result{{ response.StatusCode }} = (_responseText === "" ? null : <{{ response.Type }}>JSON.parse(resultData{{ response.StatusCode }}, this.jsonParseReviver)); } +catch(err) { result{{ response.StatusCode }} = _responseText; } {% endif -%} {% else -%} {% if response.UseDtoClass or response.IsDateOrDateTime -%} -let resultData{{ response.StatusCode }} = _responseText === "" ? null : {% if operation.HandleReferences %}jsonParse{% else %}JSON.parse{% endif %}(_responseText, this.jsonParseReviver); +let result{{ response.StatusCode }} = _responseText === "" ? null : {% if operation.HandleReferences %}jsonParse{% else %}JSON.parse{% endif %}(_responseText, this.jsonParseReviver); {{ response.DataConversionCode }} {% else -%} result{{ response.StatusCode }} = _responseText === "" ? null : <{{ response.Type }}>{% if operation.HandleReferences %}jsonParse{% else %}JSON.parse{% endif %}(_responseText, this.jsonParseReviver); From 4a43934d63b1476051eb236563ecb644bd254f2c Mon Sep 17 00:00:00 2001 From: Zachary Dow Date: Thu, 25 Sep 2025 17:28:11 -0700 Subject: [PATCH 3/3] Axios Safe JSON parsing #2927 JSON.parse will throw on any input that isn't a string. Interceptors may change the data to return as a valid JS object/array/etc. --- .../Templates/Client.ProcessResponse.HandleStatusCode.liquid | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/NSwag.CodeGeneration.TypeScript/Templates/Client.ProcessResponse.HandleStatusCode.liquid b/src/NSwag.CodeGeneration.TypeScript/Templates/Client.ProcessResponse.HandleStatusCode.liquid index 58e545ed61..544c0ffa89 100644 --- a/src/NSwag.CodeGeneration.TypeScript/Templates/Client.ProcessResponse.HandleStatusCode.liquid +++ b/src/NSwag.CodeGeneration.TypeScript/Templates/Client.ProcessResponse.HandleStatusCode.liquid @@ -44,7 +44,8 @@ let resultData{{ response.StatusCode }} = _responseText; {% if response.UseDtoClass -%} {{ response.DataConversionCode }} {% else -%} -result{{ response.StatusCode }} = {% unless response.IsPlainText %}JSON.parse({% endunless %}resultData{{ response.StatusCode }}{% unless response.IsPlainText %}){% endunless %}; +try { result{{ response.StatusCode }} = {% unless response.IsPlainText %}JSON.parse({% endunless %}resultData{{ response.StatusCode }}{% unless response.IsPlainText %}){% endunless %}; } +catch(err) { result{{ response.StatusCode }} = resultData{{ response.StatusCode }}; } {% endif -%} {% else -%} {% if response.UseDtoClass or response.IsDateOrDateTime -%}