Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

php/support primary error message #3439

Merged
merged 12 commits into from
Oct 11, 2023
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Added

- Support for primary error message in PHP [#3276](https://github.com/microsoft/kiota/issues/3276)

### Changed

## [1.7.0] - 2023-10-05
Expand Down
1 change: 1 addition & 0 deletions src/Kiota.Builder/Refiners/PhpRefiner.cs
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ public override Task Refine(CodeNamespace generatedCode, CancellationToken cance
false);
ReplaceReservedNames(generatedCode, new PhpReservedNamesProvider(), reservedWord => $"Escaped{reservedWord.ToFirstCharacterUpperCase()}", new HashSet<Type> { typeof(CodeEnumOption) });
AddQueryParameterFactoryMethod(generatedCode);
AddPrimaryErrorMessage(generatedCode, "getPrimaryErrorMessage", () => new CodeType { IsExternal = true, IsNullable = false, Name = "string" });
CorrectCoreType(generatedCode, CorrectMethodType, CorrectPropertyType, CorrectImplements);
AddParsableImplementsForModelClasses(generatedCode, "Parsable");
AddRequestConfigurationConstructors(generatedCode);
Expand Down
21 changes: 21 additions & 0 deletions src/Kiota.Builder/Writers/Php/CodeMethodWriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ public override void WriteCodeElement(CodeMethod codeElement, LanguageWriter wri

switch (codeElement.Kind)
{
case CodeMethodKind.ErrorMessageOverride:
WriteErrorMessageOverride(parentClass, writer);
break;
case CodeMethodKind.Constructor:
WriteConstructorBody(parentClass, codeElement, writer, inherits);
break;
Expand Down Expand Up @@ -78,6 +81,24 @@ public override void WriteCodeElement(CodeMethod codeElement, LanguageWriter wri
writer.WriteLine();
}

private void WriteErrorMessageOverride(CodeClass parentClass, LanguageWriter writer)
{
if (parentClass.IsErrorDefinition && parentClass.GetPrimaryMessageCodePath(static x => x.Name.ToFirstCharacterLowerCase(), static x => x.Name.ToFirstCharacterLowerCase() + "()", pathSegment: "->") is { } primaryMessageCodePath && !string.IsNullOrEmpty(primaryMessageCodePath))
{
var withoutMessage = primaryMessageCodePath.TrimEnd("->getMessage()".ToCharArray()) + "()";
var primaryErrorVariableName = "$primaryError";
writer.WriteLine($"{primaryErrorVariableName} = $this->{withoutMessage};");
writer.WriteLine($"if ({primaryErrorVariableName} !== null) {{");
writer.IncreaseIndent();
writer.WriteLine($"return {primaryErrorVariableName}->getMessage() ?? '';");
writer.CloseBlock();
writer.WriteLine("return '';");
}
else
{
writer.WriteLine("return parent::getMessage();");
}
}
private const string UrlTemplateTempVarName = "$urlTplParams";
private const string RawUrlParameterKey = "request-raw-url";
private static readonly Dictionary<CodeParameterKind, CodePropertyKind> propertiesToAssign = new Dictionary<CodeParameterKind, CodePropertyKind>()
Expand Down
2 changes: 2 additions & 0 deletions src/Kiota.Builder/Writers/Php/CodePropertyWriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ public override void WriteCodeElement(CodeProperty codeElement, LanguageWriter w
var propertyAccess = conventions.GetAccessModifier(codeElement.Access);
switch (codeElement.Kind)
{
case CodePropertyKind.ErrorMessageOverride:
throw new InvalidOperationException("Error message overrides are implemented with methods in PHP.");
case CodePropertyKind.RequestBuilder:
WriteRequestBuilderBody(codeElement, writer, propertyType, propertyAccess, propertyName);
break;
Expand Down
14 changes: 12 additions & 2 deletions tests/Kiota.Builder.Tests/Refiners/PhpLanguageRefinerTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -133,19 +133,29 @@ public async Task AddsExceptionInheritanceOnErrorClasses()
{
Type = new CodeType
{
Name = "integer"
Name = "string"
},
Name = "message",
}
);
model.AddMethod(new
CodeMethod
{
ReturnType = new CodeType
{
Name = "string"
},
Kind = CodeMethodKind.ErrorMessageOverride
});
await ILanguageRefiner.Refine(new GenerationConfiguration { Language = GenerationLanguage.PHP }, root);

var declaration = model.StartBlock;

Assert.Contains("ApiException", declaration.Usings.Select(x => x.Name));
Assert.Equal("ApiException", declaration.Inherits.Name);
Assert.Equal("ApiException", declaration.Inherits!.Name);
Assert.Contains("escapedMessage", model.Properties.Select(x => x.Name));
Assert.Contains("escapedCode", model.Properties.Select(x => x.Name));
Assert.Contains("getPrimaryErrorMessage", model.Methods.Select(x => x?.Name));
}

[Fact]
Expand Down
25 changes: 25 additions & 0 deletions tests/Kiota.Builder.Tests/Writers/Php/CodeMethodWriterTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,31 @@ public async void WriteRequestExecutor()
Assert.Contains("return $this->requestAdapter->sendPrimitiveAsync($requestInfo, StreamInterface::class, $errorMappings);", result);
}

[Fact]
public async Task WriteErrorMessageOverride()
{
setup();
var error401 = root.AddClass(new CodeClass
{
Name = "Error401",
IsErrorDefinition = true
}).First();
error401.AddProperty(new CodeProperty { Type = new CodeType { Name = "string" }, Name = "code", Kind = CodePropertyKind.Custom });
error401.AddProperty(new CodeProperty { Type = new CodeType { Name = "string" }, Name = "message", IsPrimaryErrorMessage = true, Kind = CodePropertyKind.Custom });

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

Assert.Contains("return $primaryError->getMessage() ?? '';", result);
}
[Fact]
public async void WritesRequestExecutorForEnumTypes()
{
Expand Down