microsoft / kiota

OpenAPI based HTTP Client code generator

Home Page:https://aka.ms/kiota/docs

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Why doesn't Kiota generate error mappings for strings?

balloman opened this issue · comments

I went down quite the rabbit hole, even looking through the tests, trying to figure out why I wasn't getting error mappings in my C# client. I come to find out that it's intended that unless the error have a specific json body, no error mapping is generated. What is the reason for this?

If I put an error into the spec, that's because I want the caller to be aware that the error can occur. Currently, unless it has its own object, there is nothing provided by Kiota, no documentation, no possible exception to catch, or anything at all.

Is there an option that I'm missing somewhere to enable this, or do I have to update all of my error schemas to be json?

Hi @balloman
Thanks for using kiota and for reaching out.
The main reason why this isn't supported is because kiota emits errors as exceptions, so an object type is needed for this derivation to work.
However, it's not the first time we hear about APIs that return a simple string, and there could be a special case so a wrapper type is generated that can parse the plain string.
If we provided you guidance on how to implement that change, is this something you'd be interesting in submitting a pull request for?

Hi @baywet ,

I see, that makes sense. I'd be interested in submitting a PR to fix this for sure.

Here are some details, let us know if you need more information.

Here is roughly what's generated for an object type error today

        public static ODataError CreateFromDiscriminatorValue(IParseNode parseNode)
        {
            _ = parseNode ?? throw new ArgumentNullException(nameof(parseNode));
            return new ODataError();
        }
        public virtual IDictionary<string, Action<IParseNode>> GetFieldDeserializers()
        {
            return new Dictionary<string, Action<IParseNode>>
            {
                {"error", n => { Error = n.GetObjectValue<MainError>(MainError.CreateFromDiscriminatorValue); } },
            };
        }
        public virtual void Serialize(ISerializationWriter writer)
        {
            _ = writer ?? throw new ArgumentNullException(nameof(writer));
            writer.WriteObjectValue<MainError>("error", Error);
            writer.WriteAdditionalData(AdditionalData);
        }

Assuming we introduce a wrapper type with a property, here is what it should look like

        public static ODataError CreateFromDiscriminatorValue(IParseNode parseNode)
        {
            _ = parseNode ?? throw new ArgumentNullException(nameof(parseNode));
            return new ODataError();
                 SpecialCasedProperty = parseNode.GetStringValue()
            };
        }// a little bit of work required in the method writer
        public virtual IDictionary<string, Action<IParseNode>> GetFieldDeserializers()
        {
            return new Dictionary<string, Action<IParseNode>>();
        } // this will happen automatically 
        public virtual void Serialize(ISerializationWriter writer)
        {
            _ = writer ?? throw new ArgumentNullException(nameof(writer));
            writer.WriteAdditionalData(AdditionalData);
        }// this will happen automatically

For that to happen, you'd need to add a special case for a string schema in the main builder.
Don't forget to set the primary error message flag at the same time so the exception message bubbles up properly.

And we'd probably need a new property kind so the serialization code for that special property is omitted.

And lastly, you'll need to update the factory method body by introducing a new case.

Let us know if you have further questions!

This issue has been automatically marked as stale because it has been marked as requiring author feedback but has not had any activity for 4 days. It will be closed if no further activity occurs within 3 days of this comment.