Repository: microsoft/kiota (csharp)

Issue:
Generated enum parsing methods should return nil in the default case.
### What are you generating using Kiota, clients or plugins?

API Client/SDK

### In what context or format are you using Kiota?

Source Build

### Client library/SDK language

Go

### Describe the bug

Related to https://github.com/microsoftgraph/msgraph-beta-sdk-go/issues/410 and https://github.com/microsoft/kiota-abstractions-dotnet/issues/277

At the moment, enum parsing functions are generated with the default case returning an error. This causes failure of parsing the entire payload in such scenarios where the API is updated. To be more lenient and align with other languages, the parsing methods should return nil rather than throwing an error. 

### Expected behavior

Return nil for the default case. 

we could make the change on the parsing side without causing a breaking change since:
[the parsing methods already return a pointer](https://github.com/microsoftgraph/msgraph-beta-sdk-go/blob/fc7c088142b5488e1727c9d8e2b0adf4536195e4/models/body_type.go#L15)
[the parse node interface returns any, which can be nil](https://github.com/microsoft/kiota-abstractions-go/blob/419845741fb7eb4cbfa347921f87e29c45a47cfd/serialization/parse_node.go#L48)

### How to reproduce

Make a request to a an api that returns an undocumented enum member, error is thrown preventing the parsing of the entire payload.

### Open API description file

_No response_

### Kiota Version

main

### Latest Kiota version known to work for scenario above?(Not required)

_No response_

### Known Workarounds

_No response_

### Configuration

all

### Debug output

<details><summary>Click to expand log</summary>
```


<log output here>

```
</details>


### Other information

_No response_

Pull request:
Fixes https://github.com/microsoft/kiota/issues/4621

This PR updates the enum parsing function generation to not throw on enums that are not part of the schema to avoid total failure in scenarios where the API evolves. Related to https://github.com/microsoftgraph/msgraph-beta-sdk-go/issues/410

Generation changes validated with
- https://github.com/microsoft/kiota-samples/pull/5663
- https://github.com/microsoftgraph/msgraph-sdk-go/pull/706 

Library parsing changes validate with https://github.com/microsoft/kiota-serialization-json-go/pull/136

Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 98de651760..78880149ff 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -21,6 +21,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
 - Fixed `InvalidOperationException` thrown when serializing IBacked models with no changes present in the additional data in dotnet [microsoftgraph/msgraph-sdk-dotnet#2471](https://github.com/microsoftgraph/msgraph-sdk-dotnet/issues/2471).
 - Fixed `RequestConfiguration` Classes dropped in RequestBuilder methods in python [#4535](https://github.com/microsoft/kiota/issues/4535)
 - Fixed incorrect optional types in method parameters in Python [#4507](https://github.com/microsoft/kiota/issues/4507)
+- Changed enum parsing methods to return nil in the default case in Go [#4621](https://github.com/microsoft/kiota/issues/4621)
 - Changes the cached description file name to `openapi.yml|json` from `description.yml|json` [#4641](https://github.com/microsoft/kiota/issues/4641)
 
 ## [1.14.0] - 2024-05-02
diff --git a/src/Kiota.Builder/Refiners/GoRefiner.cs b/src/Kiota.Builder/Refiners/GoRefiner.cs
index 7dafcd70f0..191497d776 100644
--- a/src/Kiota.Builder/Refiners/GoRefiner.cs
+++ b/src/Kiota.Builder/Refiners/GoRefiner.cs
@@ -525,20 +525,12 @@ private static void ReplaceRequestBuilderPropertiesByMethods(CodeElement current
     }
     private static void AddErrorAndStringsImportForEnums(CodeElement currentElement)
     {
-        if (currentElement is CodeEnum currentEnum)
+        if (currentElement is CodeEnum { Flags: true } currentEnum)
         {
             currentEnum.AddUsing(new CodeUsing
             {
-                Name = "errors",
+                Name = "strings",
             });
-
-            if (currentEnum.Flags)
-            {
-                currentEnum.AddUsing(new CodeUsing
-                {
-                    Name = "strings",
-                });
-            }
         }
         CrawlTree(currentElement, AddErrorAndStringsImportForEnums);
     }
diff --git a/src/Kiota.Builder/Writers/Go/CodeEnumWriter.cs b/src/Kiota.Builder/Writers/Go/CodeEnumWriter.cs
index ecb596c681..ffc3426e82 100644
--- a/src/Kiota.Builder/Writers/Go/CodeEnumWriter.cs
+++ b/src/Kiota.Builder/Writers/Go/CodeEnumWriter.cs
@@ -49,11 +49,11 @@ public override void WriteCodeElement(CodeEnum codeElement, LanguageWriter write
 
         WriteStringFunction(codeElement, writer, isMultiValue);
         WriteParsableEnum(codeElement, writer, isMultiValue);
-        WriteSerializeFunction(codeElement, writer, isMultiValue);
+        WriteSerializeFunction(codeElement, writer);
         WriteMultiValueFunction(codeElement, writer, isMultiValue);
     }
 
-    private void WriteStringFunction(CodeEnum codeElement, LanguageWriter writer, bool isMultiValue)
+    private static void WriteStringFunction(CodeEnum codeElement, LanguageWriter writer, bool isMultiValue)
     {
         var typeName = codeElement.Name.ToFirstCharacterUpperCase();
         var enumOptions = codeElement.Options.ToList();
@@ -86,10 +86,10 @@ private void WriteStringFunction(CodeEnum codeElement, LanguageWriter writer, bo
         }
     }
 
-    private void WriteParsableEnum(CodeEnum codeElement, LanguageWriter writer, Boolean isMultiValue)
+    private static void WriteParsableEnum(CodeEnum codeElement, LanguageWriter writer, Boolean isMultiValue)
     {
         var typeName = codeElement.Name.ToFirstCharacterUpperCase();
-        var enumOptions = codeElement.Options;
+        var enumOptions = codeElement.Options.ToArray();
 
         writer.StartBlock($"func Parse{typeName}(v string) (any, error) {{");
 
@@ -108,7 +108,7 @@ private void WriteParsableEnum(CodeEnum codeElement, LanguageWriter writer, Bool
         }
         else
         {
-            writer.WriteLine($"result := {enumOptions.First().Name.ToUpperInvariant()}_{typeName.ToUpperInvariant()}");
+            writer.WriteLine($"result := {enumOptions[0].Name.ToUpperInvariant()}_{typeName.ToUpperInvariant()}");
             writer.StartBlock("switch v {");
             foreach (var item in enumOptions)
             {
@@ -118,9 +118,8 @@ private void WriteParsableEnum(CodeEnum codeElement, LanguageWriter writer, Bool
             }
         }
 
-
         writer.StartBlock("default:");
-        writer.WriteLine($"return 0, errors.New(\"Unknown {typeName} value: \" + v)");
+        writer.WriteLine($"return nil, nil");
         writer.DecreaseIndent();
         writer.CloseBlock();
         if (isMultiValue) writer.CloseBlock();
@@ -128,7 +127,7 @@ private void WriteParsableEnum(CodeEnum codeElement, LanguageWriter writer, Bool
         writer.CloseBlock();
     }
 
-    private void WriteSerializeFunction(CodeEnum codeElement, LanguageWriter writer, Boolean isMultiValue)
+    private static void WriteSerializeFunction(CodeEnum codeElement, LanguageWriter writer)
     {
         var typeName = codeElement.Name.ToFirstCharacterUpperCase();
         writer.StartBlock($"func Serialize{typeName}(values []{typeName}) []string {{");
@@ -141,7 +140,7 @@ private void WriteSerializeFunction(CodeEnum codeElement, LanguageWriter writer,
         writer.CloseBlock();
     }
 
-    private void WriteMultiValueFunction(CodeEnum codeElement, LanguageWriter writer, Boolean isMultiValue)
+    private static void WriteMultiValueFunction(CodeEnum codeElement, LanguageWriter writer, Boolean isMultiValue)
     {
         var typeName = codeElement.Name.ToFirstCharacterUpperCase();
         writer.StartBlock($"func (i {typeName}) isMultiValue() bool {{");


Test patch:
diff --git a/tests/Kiota.Builder.Tests/Refiners/GoLanguageRefinerTests.cs b/tests/Kiota.Builder.Tests/Refiners/GoLanguageRefinerTests.cs
index 170c31dafc..f080ab861d 100644
--- a/tests/Kiota.Builder.Tests/Refiners/GoLanguageRefinerTests.cs
+++ b/tests/Kiota.Builder.Tests/Refiners/GoLanguageRefinerTests.cs
@@ -911,7 +911,7 @@ public async Task AddsErrorImportForEnumsForMultiValueEnum()
             Flags = true
         }).First();
         await ILanguageRefiner.Refine(new GenerationConfiguration { Language = GenerationLanguage.Go }, root);
-        Assert.Single(testEnum.Usings.Where(static x => "errors".Equals(x.Name, StringComparison.Ordinal)));
+        Assert.Empty(testEnum.Usings.Where(static x => "errors".Equals(x.Name, StringComparison.Ordinal)));
         Assert.Single(testEnum.Usings.Where(static x => "strings".Equals(x.Name, StringComparison.Ordinal)));
     }
     [Fact]
@@ -923,7 +923,7 @@ public async Task AddsErrorImportForEnumsForSingleValueEnum()
             Flags = false
         }).First();
         await ILanguageRefiner.Refine(new GenerationConfiguration { Language = GenerationLanguage.Go }, root);
-        Assert.Single(testEnum.Usings.Where(static x => "errors".Equals(x.Name, StringComparison.Ordinal)));
+        Assert.Empty(testEnum.Usings.Where(static x => "errors".Equals(x.Name, StringComparison.Ordinal)));
         Assert.Empty(testEnum.Usings.Where(static x => "strings".Equals(x.Name, StringComparison.Ordinal)));
     }
     [Fact]
diff --git a/tests/Kiota.Builder.Tests/Writers/Go/CodeEnumWriterTests.cs b/tests/Kiota.Builder.Tests/Writers/Go/CodeEnumWriterTests.cs
index 91b0c5514f..85a0453853 100644
--- a/tests/Kiota.Builder.Tests/Writers/Go/CodeEnumWriterTests.cs
+++ b/tests/Kiota.Builder.Tests/Writers/Go/CodeEnumWriterTests.cs
@@ -54,7 +54,7 @@ public void WritesSingleValueEnum()
         Assert.Contains("default", result);
         Assert.Contains("result :=", result);
         Assert.Contains("return &result, nil", result);
-        Assert.Contains("return 0, errors.New(\"Unknown ", result);
+        Assert.Contains("return nil, nil", result);
         AssertExtensions.CurlyBracesAreClosed(result);
         Assert.Contains(optionName.ToUpperInvariant(), result);
         Assert.Contains("func (i SomeEnum) isMultiValue() bool {", result);
@@ -96,7 +96,7 @@ public void WritesMultiValueEnum()
         Assert.Contains("default", result);
         Assert.Contains("result :=", result);
         Assert.Contains("return &result, nil", result);
-        Assert.Contains("return 0, errors.New(\"Unknown ", result);
+        Assert.Contains("return nil, nil", result);
         Assert.Contains("func (i MultiValueEnum) isMultiValue() bool {", result);
         Assert.Contains("return true", result);
         AssertExtensions.CurlyBracesAreClosed(result);