Skip to content
Open
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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added

- Added support for OpenAPI 3.2.0
- Added HTTP status code to API exception messages by default for all languages except TypeScript

### Changed

Expand Down
7 changes: 4 additions & 3 deletions src/Kiota.Builder/Refiners/GoRefiner.cs
Original file line number Diff line number Diff line change
Expand Up @@ -117,9 +117,6 @@ public override Task RefineAsync(CodeNamespace generatedCode, CancellationToken
true,
false,
true);
AddDefaultImports(
generatedCode,
defaultUsingEvaluators);
CorrectCoreType(
generatedCode,
CorrectMethodType,
Expand Down Expand Up @@ -218,6 +215,9 @@ public override Task RefineAsync(CodeNamespace generatedCode, CancellationToken
"Error",
() => new CodeType { Name = "string", IsNullable = false, IsExternal = true }
);
AddDefaultImports(
generatedCode,
defaultUsingEvaluators);
GenerateCodeFiles(generatedCode);
}, cancellationToken);
}
Expand Down Expand Up @@ -821,6 +821,7 @@ x.Type is CodeType pType &&
new (static x => x is CodeMethod @method && @method.IsOfKind(CodeMethodKind.RequestExecutor) && (method.ReturnType.Name.Equals(KiotaBuilder.UntypedNodeName, StringComparison.OrdinalIgnoreCase) ||
method.Parameters.Any(x => x.Kind is CodeParameterKind.RequestBody && x.Type.Name.Equals(KiotaBuilder.UntypedNodeName, StringComparison.OrdinalIgnoreCase))),
SerializationNamespaceName, KiotaBuilder.UntypedNodeName),
new (static x => x is CodeMethod method && method.IsOfKind(CodeMethodKind.ErrorMessageOverride), "fmt", "*fmt"),
new (static x => x is CodeEnum @enum && @enum.Flags,"", "math"),
};
private const string MultipartBodyClassName = "MultipartBody";
Expand Down
2 changes: 1 addition & 1 deletion src/Kiota.Builder/Writers/CSharp/CodePropertyWriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ private void WritePropertyInternal(CodeProperty codeElement, LanguageWriter writ
if (parentClass.GetPrimaryMessageCodePath(static x => x.Name.ToFirstCharacterUpperCase(), static x => x.Name.ToFirstCharacterUpperCase(), "?.") is string primaryMessageCodePath && !string.IsNullOrEmpty(primaryMessageCodePath))
writer.WriteLine($"public override {propertyType} {codeElement.Name.ToFirstCharacterUpperCase()} {{ get => {primaryMessageCodePath} ?? string.Empty; }}");
else
writer.WriteLine($"public override {propertyType} {codeElement.Name.ToFirstCharacterUpperCase()} {{ get => base.Message; }}");
writer.WriteLine($"public override {propertyType} {codeElement.Name.ToFirstCharacterUpperCase()} {{ get => $\"{{ResponseStatusCode}}: {{base.Message}}\"; }}");
break;
case CodePropertyKind.QueryParameter when codeElement.IsNameEscaped:
writer.WriteLine($"[QueryParameter(\"{codeElement.SerializationName}\")]");
Expand Down
3 changes: 2 additions & 1 deletion src/Kiota.Builder/Writers/Dart/CodePropertyWriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,8 @@ private void WritePropertyInternal(CodeProperty codeElement, LanguageWriter writ
break;
case CodePropertyKind.ErrorMessageOverride when parentClass.IsErrorDefinition:
writer.WriteLine("@override");
goto default;
writer.WriteLine($"{propertyType} get {codeElement.Name} => '$responseStatusCode: ${{super.message}}';");
break;
case CodePropertyKind.QueryParameter when codeElement.IsNameEscaped:
writer.WriteLine($"/// @QueryParameter('{codeElement.SerializationName}')");
goto default;
Expand Down
2 changes: 1 addition & 1 deletion src/Kiota.Builder/Writers/Go/CodeMethodWriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ private static void WriteErrorMethodOverride(CodeClass parentClass, LanguageWrit
}
else
{
writer.WriteLine("return m.ApiError.Error()");
writer.WriteLine("return fmt.Sprintf(\"%d: %s\", m.ResponseStatusCode, m.ApiError.Error())");
}
}
private void WriteRawUrlBuilderBody(CodeClass parentClass, CodeMethod codeElement, LanguageWriter writer)
Expand Down
2 changes: 1 addition & 1 deletion src/Kiota.Builder/Writers/Java/CodeMethodWriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ private static void WriteErrorMethodOverride(CodeClass parentClass, LanguageWrit
}
else
{
writer.WriteLine("return super.getMessage();");
writer.WriteLine("return getResponseStatusCode() + \": \" + super.getMessage();");
}
}
private void WriteRawUrlBuilderBody(CodeClass parentClass, CodeMethod codeElement, LanguageWriter writer)
Expand Down
2 changes: 1 addition & 1 deletion src/Kiota.Builder/Writers/Php/CodeMethodWriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ private void WriteErrorMessageOverride(CodeClass parentClass, LanguageWriter wri
}
else
{
writer.WriteLine("return parent::getMessage();");
writer.WriteLine("return $this->getResponseStatusCode() . ': ' . parent::getMessage();");
}
}
private const string UrlTemplateTempVarName = "$urlTplParams";
Expand Down
2 changes: 1 addition & 1 deletion src/Kiota.Builder/Writers/Python/CodePropertyWriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ public override void WriteCodeElement(CodeProperty codeElement, LanguageWriter w
writer.WriteLine("return ''");
}
else
writer.WriteLine("return super().message");
writer.WriteLine("return f'{self.response_status_code}: {super().message}'");
writer.DecreaseIndent();
break;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -250,5 +250,29 @@ public void WritesMessageOverrideOnPrimary()
// Then
Assert.Contains("public override string Message { get => Prop1 ?? string.Empty; }", result);
}

[Fact]
public void WritesMessageOverrideWithStatusCodeWhenNoPrimaryMessage()
{
// Given
parentClass.IsErrorDefinition = true;
// No primary error message property added
var overrideProperty = parentClass.AddProperty(new CodeProperty
{
Name = "Message",
Kind = CodePropertyKind.ErrorMessageOverride,
Type = new CodeType
{
Name = "string",
},
}).First();

// When
writer.Write(overrideProperty);
var result = tw.ToString();

// Then
Assert.Contains("public override string Message { get => $\"{ResponseStatusCode}: {base.Message}\"; }", result);
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -132,4 +132,15 @@ public void DoesntWritePropertiesExistingInParentType()
var result = tw.ToString();
Assert.Empty(result);
}

[Fact]
public void WriteErrorMessageOverrideWithStatusCodeWhenNoPrimary()
{
property.Kind = CodePropertyKind.ErrorMessageOverride;
parentClass.IsErrorDefinition = true;
writer.Write(property);
var result = tw.ToString();
Assert.Contains("@override", result);
Assert.Contains("get propertyName => '$responseStatusCode: ${super.message}';", result);
}
}
65 changes: 65 additions & 0 deletions tests/Kiota.Builder.Tests/Writers/Go/CodeMethodWriterTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2305,6 +2305,71 @@ public void WritesMessageOverrideOnPrimary()
Assert.Contains("return *(m.GetProp1()", result);
}

[Fact]
public void WritesMessageOverrideWithStatusCodeWhenNoPrimary()
{
// Given
parentClass = root.AddClass(new CodeClass
{
Name = "parentClass",
IsErrorDefinition = true,
Kind = CodeClassKind.Model,
}).First();
// No primary error message property added
var method = parentClass.AddMethod(new CodeMethod
{
Kind = CodeMethodKind.ErrorMessageOverride,
ReturnType = new CodeType
{
Name = "string",
IsNullable = false,
},
IsAsync = false,
IsStatic = false,
Name = "Error"
}).First();

// When
writer.Write(method);
var result = tw.ToString();

// Then
Assert.Contains("Error()(string) {", result);
Assert.Contains("return fmt.Sprintf(\"%d: %s\", m.ResponseStatusCode, m.ApiError.Error())", result);
}

[Fact]
public async Task AddsFormatImportForErrorMessageOverride()
{
// Given
parentClass = root.AddClass(new CodeClass
{
Name = "parentClass",
IsErrorDefinition = true,
Kind = CodeClassKind.Model,
}).First();
var method = parentClass.AddMethod(new CodeMethod
{
Kind = CodeMethodKind.ErrorMessageOverride,
ReturnType = new CodeType
{
Name = "string",
IsNullable = false,
},
IsAsync = false,
IsStatic = false,
Name = "Error"
}).First();

// When - Run refiner to add imports
await ILanguageRefiner.RefineAsync(new GenerationConfiguration { Language = GenerationLanguage.Go }, root);

// Then - Verify fmt import was added by the refiner
var fmtUsing = parentClass.StartBlock.Usings.FirstOrDefault(u => u.Declaration?.Name == "fmt");
Assert.NotNull(fmtUsing);
Assert.Equal("*fmt", fmtUsing.Name);
}

[Fact]
public void WritesRequestGeneratorAcceptHeaderQuotes()
{
Expand Down
34 changes: 34 additions & 0 deletions tests/Kiota.Builder.Tests/Writers/Java/CodeMethodWriterTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2166,6 +2166,40 @@ public void WritesMessageOverrideOnPrimary()
Assert.Contains("return this.getProp1()", result);
}

[Fact]
public void WritesMessageOverrideWithStatusCodeWhenNoPrimary()
{
// Given
parentClass = root.AddClass(new CodeClass
{
Name = "parentClass",
IsErrorDefinition = true,
Kind = CodeClassKind.Model,
}).First();
// No primary error message property added
var method = parentClass.AddMethod(new CodeMethod
{
Kind = CodeMethodKind.ErrorMessageOverride,
ReturnType = new CodeType
{
Name = "String",
IsNullable = false,
},
IsAsync = false,
IsStatic = false,
Name = "getErrorMessage"
}).First();

// When
writer.Write(method);
var result = tw.ToString();

// Then
Assert.Contains("@Override", result);
Assert.Contains("String getErrorMessage() ", result);
Assert.Contains("return getResponseStatusCode() + \": \" + super.getMessage();", result);
}

[Fact]
public void WritesRequestGeneratorAcceptHeaderQuotes()
{
Expand Down
26 changes: 26 additions & 0 deletions tests/Kiota.Builder.Tests/Writers/Php/CodeMethodWriterTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -319,6 +319,32 @@ public async Task WriteErrorMessageOverrideAsync()

Assert.Contains("return $primaryError->getMessage() ?? '';", result);
}

[Fact]
public async Task WriteErrorMessageOverrideWithStatusCodeWhenNoPrimaryAsync()
{
setup();
var error401 = root.AddClass(new CodeClass
{
Name = "Error401",
IsErrorDefinition = true
}).First();
// No primary error message property added

var codeMethod = new CodeMethod
{
Kind = CodeMethodKind.ErrorMessageOverride,
ReturnType = new CodeType { Name = "string" },
SimpleName = "getPrimaryErrorMessage",
};
error401.AddMethod(codeMethod);
await ILanguageRefiner.RefineAsync(new GenerationConfiguration { Language = GenerationLanguage.PHP }, root);
_codeMethodWriter.WriteCodeElement(codeMethod, languageWriter);
var result = stringWriter.ToString();

Assert.Contains("return $this->getResponseStatusCode() . ': ' . parent::getMessage();", result);
}

[Fact]
public async Task WritesRequestExecutorForEnumTypesAsync()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,17 @@ public void WritePrimaryErrorMessagePropertyOption1()
var result = tw.ToString();
Assert.Contains("super().message", result);
}

[Fact]
public void WriteMessageOverrideWithStatusCodeWhenNoPrimary()
{
property.Kind = CodePropertyKind.ErrorMessageOverride;
parentClass.IsErrorDefinition = true;
writer.Write(property);
var result = tw.ToString();
Assert.Contains("return f'{self.response_status_code}: {super().message}'", result);
}

[Fact]
public void WritePrimaryErrorMessagePropertyOption2()
{
Expand Down