Skip to content

Commit d0870b5

Browse files
committed
fix: address review feedback on typed errors
- Fix errors.go doc: clarify errors.As for classification, errors.Is for sentinels - Preserve context in NotFound messages for parameter/return type validation - Include full message in navigation profile NotFound error - Use ValidationError for version parse failures instead of BackendError - Include 'unsupported' prefix in container type UnsupportedError message
1 parent caed015 commit d0870b5

5 files changed

Lines changed: 16 additions & 9 deletions

File tree

mdl/errors/errors.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@
22

33
// Package mdlerrors provides structured error types for the MDL executor.
44
//
5-
// All error types support errors.Is and errors.As for programmatic classification.
5+
// Typed errors support errors.As for programmatic classification.
6+
// Sentinel or wrapped errors may also support errors.Is where applicable
7+
// (for example, ErrExit and BackendError via Unwrap).
68
// Every error preserves the original message via Error() for backward-compatible
79
// string output — callers that only use %v or .Error() see no change.
810
//

mdl/executor/cmd_features.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,15 +61,15 @@ func (e *Executor) execShowFeatures(s *ast.ShowFeaturesStmt) error {
6161
// SHOW FEATURES ADDED SINCE x.y
6262
sinceV, err := versions.ParseSemVer(s.AddedSince)
6363
if err != nil {
64-
return mdlerrors.NewBackend("parse version "+s.AddedSince, err)
64+
return mdlerrors.NewValidationf("invalid version %q: %v", s.AddedSince, err)
6565
}
6666
return e.showFeaturesAddedSince(reg, sinceV)
6767

6868
case s.ForVersion != "":
6969
// SHOW FEATURES FOR VERSION x.y — no project connection needed
7070
pv, err = versions.ParseSemVer(s.ForVersion)
7171
if err != nil {
72-
return mdlerrors.NewBackend("parse version "+s.ForVersion, err)
72+
return mdlerrors.NewValidationf("invalid version %q: %v", s.ForVersion, err)
7373
}
7474

7575
default:

mdl/executor/cmd_microflows_create.go

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -129,13 +129,15 @@ func (e *Executor) execCreateMicroflow(s *ast.CreateMicroflowStmt) error {
129129
if p.Type.EntityRef != nil && !isBuiltinModuleEntity(p.Type.EntityRef.Module) {
130130
entityID := entityResolver(*p.Type.EntityRef)
131131
if entityID == "" {
132-
return mdlerrors.NewNotFound("entity", p.Type.EntityRef.Module+"."+p.Type.EntityRef.Name)
132+
return mdlerrors.NewNotFoundMsg("entity", p.Type.EntityRef.Module+"."+p.Type.EntityRef.Name,
133+
fmt.Sprintf("entity '%s.%s' not found for parameter '%s'", p.Type.EntityRef.Module, p.Type.EntityRef.Name, p.Name))
133134
}
134135
}
135136
// Validate enumeration references for Enumeration types
136137
if p.Type.Kind == ast.TypeEnumeration && p.Type.EnumRef != nil {
137138
if found := e.findEnumeration(p.Type.EnumRef.Module, p.Type.EnumRef.Name); found == nil {
138-
return mdlerrors.NewNotFound("enumeration", p.Type.EnumRef.Module+"."+p.Type.EnumRef.Name)
139+
return mdlerrors.NewNotFoundMsg("enumeration", p.Type.EnumRef.Module+"."+p.Type.EnumRef.Name,
140+
fmt.Sprintf("enumeration '%s.%s' not found for parameter '%s'", p.Type.EnumRef.Module, p.Type.EnumRef.Name, p.Name))
139141
}
140142
}
141143
param := &microflows.MicroflowParameter{
@@ -157,13 +159,15 @@ func (e *Executor) execCreateMicroflow(s *ast.CreateMicroflowStmt) error {
157159
if s.ReturnType.Type.EntityRef != nil && !isBuiltinModuleEntity(s.ReturnType.Type.EntityRef.Module) {
158160
entityID := entityResolver(*s.ReturnType.Type.EntityRef)
159161
if entityID == "" {
160-
return mdlerrors.NewNotFound("entity", s.ReturnType.Type.EntityRef.Module+"."+s.ReturnType.Type.EntityRef.Name)
162+
return mdlerrors.NewNotFoundMsg("entity", s.ReturnType.Type.EntityRef.Module+"."+s.ReturnType.Type.EntityRef.Name,
163+
fmt.Sprintf("entity '%s.%s' not found for return type", s.ReturnType.Type.EntityRef.Module, s.ReturnType.Type.EntityRef.Name))
161164
}
162165
}
163166
// Validate enumeration references for return type
164167
if s.ReturnType.Type.Kind == ast.TypeEnumeration && s.ReturnType.Type.EnumRef != nil {
165168
if found := e.findEnumeration(s.ReturnType.Type.EnumRef.Module, s.ReturnType.Type.EnumRef.Name); found == nil {
166-
return mdlerrors.NewNotFound("enumeration", s.ReturnType.Type.EnumRef.Module+"."+s.ReturnType.Type.EnumRef.Name)
169+
return mdlerrors.NewNotFoundMsg("enumeration", s.ReturnType.Type.EnumRef.Module+"."+s.ReturnType.Type.EnumRef.Name,
170+
fmt.Sprintf("enumeration '%s.%s' not found for return type", s.ReturnType.Type.EnumRef.Module, s.ReturnType.Type.EnumRef.Name))
167171
}
168172
}
169173
mf.ReturnType = convertASTToMicroflowDataType(s.ReturnType.Type, entityResolver)

mdl/executor/cmd_navigation.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,8 @@ func (e *Executor) execAlterNavigation(s *ast.AlterNavigationStmt) error {
3333
}
3434
}
3535
if !profileFound {
36-
return mdlerrors.NewNotFoundMsg("navigation profile", s.ProfileName, fmt.Sprintf("available: %s", profileNames(nav)))
36+
return mdlerrors.NewNotFoundMsg("navigation profile", s.ProfileName,
37+
fmt.Sprintf("navigation profile not found: %s (available: %s)", s.ProfileName, profileNames(nav)))
3738
}
3839

3940
// Convert AST types to writer spec

mdl/executor/cmd_widgets.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,7 @@ func (e *Executor) updateWidgetsInContainer(containerID string, widgetRefs []wid
212212
return e.updateWidgetsInSnippet(containerID, containerName, widgetRefs, assignments, dryRun)
213213
}
214214

215-
return 0, mdlerrors.NewUnsupported(fmt.Sprintf("container type: %s", containerType))
215+
return 0, mdlerrors.NewUnsupported(fmt.Sprintf("unsupported container type: %s", containerType))
216216
}
217217

218218
// updateWidgetsInPage updates widgets in a page using raw BSON.

0 commit comments

Comments
 (0)