-
-
Notifications
You must be signed in to change notification settings - Fork 214
fix: check actual type in schema ref when enforcing non-nullable object schemas #599
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
fix: check actual type in schema ref when enforcing non-nullable object schemas #599
Conversation
WalkthroughThe changes in this pull request modify the Changes
Possibly related PRs
Suggested reviewers
Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media? 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## main #599 +/- ##
==========================================
+ Coverage 92.80% 92.82% +0.02%
==========================================
Files 22 22
Lines 3903 3915 +12
==========================================
+ Hits 3622 3634 +12
Misses 236 236
Partials 45 45 ☔ View full report in Codecov by Sentry. |
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.
Actionable comments posted: 0
🧹 Outside diff range and nitpick comments (3)
schema.go (3)
Line range hint
572-578
: Consider improving error message and handlingThe error message for unsupported nullable fields is informative, but it could be enhanced to provide more context and guidance.
Consider the following improvements:
- Use
fmt.Errorf
with%w
to wrap the error, allowing for better error handling up the call stack.- Provide more context in the error message, such as suggesting alternatives or explaining why it's not supported.
Here's an example of how you could refactor this:
-panic(fmt.Errorf("nullable is not supported for field '%s' which is type '%s'", f.Name, fs.Ref)) +return nil, fmt.Errorf("nullable is not supported for field '%s' of type '%s': %w", f.Name, fs.Ref, ErrUnsupportedNullableObject)This change assumes you've defined an
ErrUnsupportedNullableObject
error type elsewhere in your package. You'd also need to update the function signature to return(*Schema, error)
instead of just*Schema
.Consider creating a custom error type for schema-related errors. This would allow for more structured error handling throughout the application. For example:
type SchemaError struct { Field string Type string Msg string } func (e *SchemaError) Error() string { return fmt.Sprintf("schema error for field '%s' of type '%s': %s", e.Field, e.Type, e.Msg) }This would allow for more detailed error reporting and easier error handling in the calling code.
Line range hint
479-583
: Consider refactoringSchemaFromField
for improved maintainabilityThe
SchemaFromField
function is quite long and handles many different schema properties. This can make it difficult to maintain and extend in the future.Consider breaking down this function into smaller, more focused functions. Here are some suggestions:
- Create separate functions for handling different types of tags (e.g.,
handleStringTags
,handleNumericTags
, etc.).- Group related schema property settings together.
- Use a builder pattern to construct the schema, which could make the code more readable and easier to extend.
Here's a sketch of how this refactoring could look:
func SchemaFromField(registry Registry, f reflect.StructField, hint string) *Schema { fs := registry.Schema(f.Type, true, hint) if fs == nil { return fs } schemaBuilder := NewSchemaBuilder(fs) schemaBuilder. HandleStringTags(f). HandleNumericTags(f). HandleArrayTags(f). HandleObjectTags(f) handleNullableField(registry, f, schemaBuilder) return schemaBuilder.Build() } func handleNullableField(registry Registry, f reflect.StructField, builder *SchemaBuilder) { if builder.Schema.Nullable && isNullableObjectSchema(registry, builder.Schema) { // Handle nullable object schema... } }This approach would make the function easier to read, maintain, and extend in the future. It would also make it easier to add new schema properties or tag handling without cluttering the main function.
Consider introducing a
SchemaBuilder
struct that encapsulates the logic for building a schema. This could provide a more fluent interface for schema construction and make it easier to add new schema properties in the future.
Line range hint
1-583
: Summary of review for schema.goThe changes in this file successfully address the issue described in the PR objectives, improving the handling of nullable object schemas. However, there are several opportunities for further improvement:
- The main change could be refactored into a separate function for better readability and reusability.
- Error handling for unsupported nullable fields could be improved to provide more context and better integration with error handling patterns.
- The
SchemaFromField
function is quite long and complex, and could benefit from being broken down into smaller, more focused functions.- Consider introducing a
SchemaBuilder
pattern to improve the overall structure and extensibility of the schema generation code.These suggestions aim to improve the maintainability, readability, and robustness of the code. While the current changes are functional and address the immediate issue, implementing these refactoring suggestions could lead to a more sustainable codebase in the long term.
Consider creating a follow-up task to implement the suggested refactorings, as they go beyond the scope of the current PR but could significantly improve the codebase.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
📒 Files selected for processing (1)
- schema.go (1 hunks)
🧰 Additional context used
🔇 Additional comments (1)
schema.go (1)
Line range hint
564-571
: Improved handling of nullable object schemasThe changes introduce a more precise check for nullable object schemas. This adjustment addresses the issue mentioned in the PR objectives, where scalar types registered as references were incorrectly treated as non-nullable.
Consider extracting the type check into a separate function for better readability and reusability. For example:
+func isNullableObjectSchema(registry Registry, schema *Schema) bool { + return schema.Ref != "" && registry.SchemaFromRef(schema.Ref).Type == "object" +} func SchemaFromField(registry Registry, f reflect.StructField, hint string) *Schema { // ... (existing code) - if fs.Nullable && fs.Ref != "" && registry.SchemaFromRef(fs.Ref).Type == "object" { + if fs.Nullable && isNullableObjectSchema(registry, fs) { // ... (existing code) } // ... (rest of the function) }This refactoring would make the code more maintainable and easier to understand at a glance.
Let's verify if there are any other occurrences of similar checks in the codebase:
This will help us identify if this check needs to be applied consistently across the codebase.
✅ Verification successful
Verification successful: The nullable object schema check in
schema.go
is correctly implemented, and no similar patterns exist elsewhere in the codebase.🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Search for similar nullable object schema checks rg --type go 'Nullable.*Ref.*Type.*"object"'Length of output: 141
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.
Makes sense, thanks!
ca4b5f6 intends to prevent non-scalar types to be nullable in their schema definition. It does so by checking that the provided schema is not a ref.
However it is possible to end up having a ref schema for a scalar type, which should be nullable. This PR fixes this by actually checking that the schema type of the ref is
object
.Example scalar type that is purposely registered as a ref :
Summary by CodeRabbit