-
Notifications
You must be signed in to change notification settings - Fork 292
Provide an error message from Open api description #6953
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
base: main
Are you sure you want to change the base?
Provide an error message from Open api description #6953
Conversation
to be passed to base, following C# conventions
Hopefully human-readable and helpful
…rwrite any previous constructor.
baywet
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the contribution!
| errorMappings.TryAdd(errorCode, type); | ||
| if (!string.IsNullOrEmpty(description)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should the try add result be used in the condition here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As I understand it, it is quite a corner case where consumer expectations are hard to guess - for this to matter, you'd need duplicate error code mappings where one has a description and the other hasn't.
But you have seen more OpenAPI specs than I so if you say this actually happens and the current behavior is unexpected, then the answer is yes :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
actually I didn't notice but we're duplicating a lot of code with the existing method.
Please:
- add the description parameter as an optional parameter to the existing method
- move the condition to the existing method
- update the condition to consider the try add, so we don't end up in a weird state where we have a description for an error type that doesn't exist
- remove this new method
- Update the GetErrorDescriptionMethod to always check whether a matching mapping is present before returning anything (same principle, safety first)
static lambdas, simplification. Co-authored-by: Vincent Biret <vincentbiret@hotmail.com>
|
@baywet thanks for the review; I think all your points have been addressed. Is it OK to proceed with other languages in the same manner or is there still room for improvement? |
| // Then | ||
| var messageConstructor = errorClass.Methods | ||
| .FirstOrDefault(m => m.IsOfKind(CodeMethodKind.Constructor) && | ||
| m.Parameters.Any(p => p.Type.Name.Equals("string", StringComparison.OrdinalIgnoreCase) && p.Name.Equals("message", StringComparison.OrdinalIgnoreCase))); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this should test on the new kind that was introduced (multiple instances)
| } | ||
| // For error classes with message constructor, pass the message to base constructor | ||
| else if (isConstructor && parentClass.IsErrorDefinition && | ||
| currentMethod.Parameters.Any(p => p.IsOfKind(CodeParameterKind.ErrorMessage))) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| currentMethod.Parameters.Any(p => p.IsOfKind(CodeParameterKind.ErrorMessage))) | |
| currentMethod.Parameters.Any(static p => p.IsOfKind(CodeParameterKind.ErrorMessage))) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's probably a static analyser trick I'm missing here that would warn contributors about lambdas that can be static?
| WriteFactoryMethodBodyForIntersectionModel(codeElement, parentClass, parseNodeParameter, writer); | ||
| else if (codeElement.IsOfKind(CodeMethodKind.FactoryWithErrorMessage)) | ||
| { | ||
| var messageParam = codeElement.Parameters.FirstOrDefault(p => p.IsOfKind(CodeParameterKind.ErrorMessage)) ?? throw new InvalidOperationException($"FactoryWithErrorMessage should have a message parameter"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| var messageParam = codeElement.Parameters.FirstOrDefault(p => p.IsOfKind(CodeParameterKind.ErrorMessage)) ?? throw new InvalidOperationException($"FactoryWithErrorMessage should have a message parameter"); | |
| var messageParam = codeElement.Parameters.FirstOrDefault(static p => p.IsOfKind(CodeParameterKind.ErrorMessage)) ?? throw new InvalidOperationException($"FactoryWithErrorMessage should have a message parameter"); |
| errorMappings.TryAdd(errorCode, type); | ||
| if (!string.IsNullOrEmpty(description)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
actually I didn't notice but we're duplicating a lot of code with the existing method.
Please:
- add the description parameter as an optional parameter to the existing method
- move the condition to the existing method
- update the condition to consider the try add, so we don't end up in a weird state where we have a description for an error type that doesn't exist
- remove this new method
- Update the GetErrorDescriptionMethod to always check whether a matching mapping is present before returning anything (same principle, safety first)
| } | ||
|
|
||
| // Add message constructor if not already present | ||
| if (!codeClass.Methods.Any(static x => x.IsOfKind(CodeMethodKind.Constructor) && x.Parameters.Any(static p => "string".Equals(p.Type.Name, StringComparison.OrdinalIgnoreCase)))) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should filter on the new kind instead of the name
| if (errorMapping.Value.AllTypes.FirstOrDefault()?.TypeDefinition is CodeClass { IsErrorDefinition: true } errorClass) | ||
| { | ||
| var errorDescription = codeElement.GetErrorDescription(errorMapping.Key); | ||
| var statusCodeAndDescription = !string.IsNullOrEmpty(errorDescription) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@baywet I'm having second thoughts on this - I think we shouldn't include the status code key here because it may be confusing in the 4XX/5XX case.
So, just the description when provided and the old behavior when not.
The actual specific response status code has value though; #6951 would help to provide that without conflicting.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do you think this would be confusing for the 4XX/5XX case?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The 5XX is not part of the API designer provided error message and the actual response code provides more detailed info. I don't see added value in an ApiException that says "400 4XX Your mistake" over "400 Your mistake".
to avoid confusion with 4xx 5xx generic codes
commit c3bc041 Author: Koen van Leeuwen <koen@logiqs.nl> Date: Sun Dec 14 15:53:41 2025 +0100 Fix python and php commit 0bd60a0 Author: Koen van Leeuwen <koen@logiqs.nl> Date: Sun Dec 14 10:53:47 2025 +0100 fix php commit 52d3a94 Author: Koen van Leeuwen <koen@logiqs.nl> Date: Sun Dec 14 10:10:12 2025 +0100 base CreateConstructor messes up the naming commit 8dac31f Author: Koen van Leeuwen <koen@logiqs.nl> Date: Sat Dec 13 12:14:15 2025 +0100 debugging the generated code commit 6138205 Author: Koen van Leeuwen <koen@logiqs.nl> Date: Sat Dec 13 11:01:29 2025 +0100 The Go writer has the last word on constructor names commit de7416f Author: Koen van Leeuwen <koen@logiqs.nl> Date: Sat Dec 13 10:20:07 2025 +0100 update tests to reflect the new proper type enums commit 87bd2b6 Author: Koen van Leeuwen <koen@logiqs.nl> Date: Sat Dec 13 09:17:39 2025 +0100 pass the parameter directly commit 271b4b0 Author: Koen van Leeuwen <koen@logiqs.nl> Date: Fri Dec 12 21:47:53 2025 +0100 refactor very similar factory creation commit 67dc075 Author: Koen van Leeuwen <koen@logiqs.nl> Date: Fri Dec 12 21:24:32 2025 +0100 remove switch/if antipattern commit e9d5bc9 Author: Koen van Leeuwen <koen@logiqs.nl> Date: Fri Dec 12 20:36:44 2025 +0100 Simplify param creation commit 4783f30 Merge: 988bce9 5a492c0 Author: Koen van Leeuwen <koen@logiqs.nl> Date: Fri Dec 12 20:08:49 2025 +0100 Merge remote-tracking branch 'upstream/main' into OpenAPI-description-in-exceptions-other-languages commit 988bce9 Author: Koen van Leeuwen <koen@logiqs.nl> Date: Fri Dec 12 20:06:51 2025 +0100 Inline factory method generation to align with other languages commit 56c37ae Author: Koen van Leeuwen <koen@logiqs.nl> Date: Fri Dec 12 19:58:13 2025 +0100 fix other tests commit 4eb5959 Author: Koen van Leeuwen <koen@logiqs.nl> Date: Fri Dec 12 15:30:55 2025 +0100 fix go commit 12f4639 Author: Koen van Leeuwen <koen@logiqs.nl> Date: Fri Dec 12 15:16:17 2025 +0100 update tests commit 7a5b295 Merge: 9ffe8c4 206e170 Author: Koen van Leeuwen <koen@logiqs.nl> Date: Fri Dec 12 08:27:18 2025 +0100 Merge remote-tracking branch 'upstream/main' into OpenAPI-description-in-exceptions-other-languages commit 9ffe8c4 Author: Koen van Leeuwen <koen@logiqs.nl> Date: Fri Dec 12 08:01:25 2025 +0100 restore merge artifact commit 7a61a84 Author: Koen van Leeuwen <koen@logiqs.nl> Date: Fri Dec 12 07:50:51 2025 +0100 extract error message parameter creation commit da6b4ed Author: Koen van Leeuwen <koen@logiqs.nl> Date: Thu Dec 11 20:38:05 2025 +0100 Add Ruby commit 38bf2ee Author: Koen van Leeuwen <koen@logiqs.nl> Date: Thu Dec 11 20:32:23 2025 +0100 cleanup Python commit 4485b78 Author: Koen van Leeuwen <koen@logiqs.nl> Date: Thu Dec 11 20:24:34 2025 +0100 cleanup PHP commit 877ad2b Author: Koen van Leeuwen <koen@logiqs.nl> Date: Thu Dec 11 20:04:47 2025 +0100 Cleanup Go commit e39a932 Author: Koen van Leeuwen <koen@logiqs.nl> Date: Thu Dec 11 19:31:12 2025 +0100 Cleanup Typescript commit fc11b7f Author: Koen van Leeuwen <koen@logiqs.nl> Date: Thu Dec 11 19:26:13 2025 +0100 Cleanup Java commit 133a78d Author: Koen van Leeuwen <koen@logiqs.nl> Date: Thu Sep 25 14:03:54 2025 +0200 feat: add OpenAPI error description enhancements for Python - Add parameterless and message constructors to Python error classes - Add create_from_discriminator_value_with_message factory method - Enhance error mappings to include human-readable descriptions - Support constructor inheritance with super().__init__(message) - Add comprehensive unit tests for refiner and method writer - Maintain backward compatibility with existing error mappings 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com> commit f3cc7be Author: Koen van Leeuwen <koen@logiqs.nl> Date: Fri Sep 26 13:46:05 2025 +0200 Implement TypeScript error description enhancements - Add constructors for error classes with optional message parameter - Add createFromDiscriminatorValueWithMessage factory methods for error classes - Enhance error mappings in CodeConstantWriter with human-readable descriptions - Add comprehensive tests for refiner and writer enhancements - Fix test expectations for non-error class factory method behavior - Correct call order for AddConstructorsForErrorClasses in TypeScript refiner pipeline 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com> commit ae746e5 Author: Koen van Leeuwen <koen@logiqs.nl> Date: Fri Sep 26 10:21:05 2025 +0200 Implement OpenAPI error description enhancements for PHP - Add constructors for error classes (__construct with parameterless and message variants) - Add createFromDiscriminatorValueWithMessage factory method for enhanced error handling - Enhance error mapping generation with human-readable descriptions using PHP function syntax - Add special handling for error factory methods in method writer - Add comprehensive tests for PHP error enhancements - Follow PHP conventions with camelCase method names and constructor patterns 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com> commit eba3aa3 Author: Koen van Leeuwen <koen@logiqs.nl> Date: Fri Sep 26 10:00:24 2025 +0200 Implement OpenAPI error description enhancements for Go - Add factory methods for error classes (NewErrorClass, NewErrorClassWithMessage, CreateFromDiscriminatorValueWithMessage) - Enhance error mapping generation with human-readable descriptions using Go function syntax - Add special handling for error factory methods in method writer - Add comprehensive tests for Go error enhancements - Follow Go conventions with factory functions and pointer returns 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com> commit 98728fd Author: Koen van Leeuwen <koen@logiqs.nl> Date: Thu Sep 25 13:36:38 2025 +0200 Add Dart commit 24ffc6e Author: Koen van Leeuwen <koen@logiqs.nl> Date: Thu Sep 25 13:24:41 2025 +0200 Add Java
See also #4349; this PR aims to change the developer experience from
to
in case the OpenAPI document provides a description per status code.
The current behavior requires an extension for pretty error messages.
Before putting some tools to work to implement this for other languages, first I'd like to check whether this feature design fits the project.
It adds a constructor with a message to error classes and adds the description from the document to the error map:
The existing extension message logic is still intact, so this is used as fallback only.