Azure / autorest.csharp

Extension for AutoRest (https://github.com/Azure/autorest) that generates C# code
MIT License
142 stars 165 forks source link

[DPG] Generation fails when using extended discriminated types as route responses #4041

Closed joseharriaga closed 8 months ago

joseharriaga commented 9 months ago

Consider the following TypeSpec:

@discriminator("type")
model DeletionStatus {
    type: string;
    deleted: boolean;
}

model AssistantFileDeletionStatus extends DeletionStatus {
  type: "assistant.file.deleted";
}

@delete
deleteAssistantFile(
    @path
    assistantId: string,

    @path
    fileId: string,
): AssistantFileDeletionStatus;

Notice how the extended discriminated type AssistantFileDeletionStatus is the response of the delete operation. This causes code generation to fail with the following error:

{"level":"info","message":"dotnet --roll-forward Major E:/azure-sdk-for-net-pr/sdk/openai/Azure.AI.OpenAI.Assistants/TempTypeSpecFiles/OpenAI.Assistants/node_modules/@autorest/csharp/AutoRest.CSharp.dll --project-path E:/azure-sdk-for-net-pr/sdk/openai/Azure.AI.OpenAI.Assistants/src   --clear-output-folder false"}
Unhandled exception. System.InvalidOperationException: Not implemented type: 'System.Object'
   at AutoRest.CSharp.Generation.Types.CSharpType.get_Implementation() in D:\a\_work\1\s\autorest.csharp\src\AutoRest.CSharp\Common\Generation\Types\CSharpType.cs:line 90
   at AutoRest.CSharp.Output.Models.Types.ObjectType.CreateExtraDescriptionWithDiscriminator() in D:\a\_work\1\s\autorest.csharp\src\AutoRest.CSharp\Common\Output\Models\Types\ObjectType.cs:line 100
   at AutoRest.CSharp.Output.Models.Types.ObjectType.get_Description() in D:\a\_work\1\s\autorest.csharp\src\AutoRest.CSharp\Common\Output\Models\Types\ObjectType.cs:line 47
   at AutoRest.CSharp.Generation.Writers.ModelWriter.WriteObjectSchema(CodeWriter writer, ObjectType schema) in D:\a\_work\1\s\autorest.csharp\src\AutoRest.CSharp\Common\Generation\Writers\ModelWriter.cs:line 47
ArcturusZhang commented 8 months ago

Hi @joseharriaga using the tsp you provided here:

@discriminator("type")
model DeletionStatus {
    type: string;
    deleted: boolean;
}

model AssistantFileDeletionStatus extends DeletionStatus {
  type: "assistant.file.deleted";
}

@delete
op deleteAssistantFile(
    @path
    assistantId: string,

    @path
    fileId: string,
): AssistantFileDeletionStatus;

I can no longer reproduce your issue, the code is properly generated:

        /// <param name="assistantId"> The <see cref="string"/> to use. </param>
        /// <param name="fileId"> The <see cref="string"/> to use. </param>
        /// <param name="cancellationToken"> The cancellation token to use. </param>
        /// <exception cref="ArgumentNullException"> <paramref name="assistantId"/> or <paramref name="fileId"/> is null. </exception>
        /// <exception cref="ArgumentException"> <paramref name="assistantId"/> or <paramref name="fileId"/> is an empty string, and was expected to be non-empty. </exception>
        /// <include file="Docs/ModelsTypeSpecClient.xml" path="doc/members/member[@name='DeleteAssistantFileAsync(string,string,CancellationToken)']/*" />
        public virtual async Task<Response<AssistantFileDeletionStatus>> DeleteAssistantFileAsync(string assistantId, string fileId, CancellationToken cancellationToken = default)
        {
            Argument.AssertNotNullOrEmpty(assistantId, nameof(assistantId));
            Argument.AssertNotNullOrEmpty(fileId, nameof(fileId));

            RequestContext context = FromCancellationToken(cancellationToken);
            Response response = await DeleteAssistantFileAsync(assistantId, fileId, context).ConfigureAwait(false);
            return Response.FromValue(AssistantFileDeletionStatus.FromResponse(response), response);
        }

        /// <param name="assistantId"> The <see cref="string"/> to use. </param>
        /// <param name="fileId"> The <see cref="string"/> to use. </param>
        /// <param name="cancellationToken"> The cancellation token to use. </param>
        /// <exception cref="ArgumentNullException"> <paramref name="assistantId"/> or <paramref name="fileId"/> is null. </exception>
        /// <exception cref="ArgumentException"> <paramref name="assistantId"/> or <paramref name="fileId"/> is an empty string, and was expected to be non-empty. </exception>
        /// <include file="Docs/ModelsTypeSpecClient.xml" path="doc/members/member[@name='DeleteAssistantFile(string,string,CancellationToken)']/*" />
        public virtual Response<AssistantFileDeletionStatus> DeleteAssistantFile(string assistantId, string fileId, CancellationToken cancellationToken = default)
        {
            Argument.AssertNotNullOrEmpty(assistantId, nameof(assistantId));
            Argument.AssertNotNullOrEmpty(fileId, nameof(fileId));

            RequestContext context = FromCancellationToken(cancellationToken);
            Response response = DeleteAssistantFile(assistantId, fileId, context);
            return Response.FromValue(AssistantFileDeletionStatus.FromResponse(response), response);
        }

therefore I believe this issue must have been fixed by our recent updates. Could you have a try again?

microsoft-github-policy-service[bot] commented 8 months ago

Hi, we're sending this friendly reminder because we haven't heard back from you in 7 days. We need more information about this issue to help address it. Please be sure to give us your input. If we don't hear back from you within 14 days of this comment the issue will be automatically closed. Thank you!