Skip to content

Commit 9be2604

Browse files
authored
Merge pull request #222 from retran/feature/typed-errors
feat: add typed error system for executor
2 parents 4346b39 + d0870b5 commit 9be2604

File tree

96 files changed

+1627
-1240
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

96 files changed

+1627
-1240
lines changed

cmd/mxcli/docker/detect.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,10 @@
1313
// CDN downloads are the primary source for mxbuild and runtime.
1414
//
1515
// Resolution priority (all platforms):
16-
// 1. Explicit path (--mxbuild-path)
17-
// 2. PATH lookup
18-
// 3. OS-specific known locations (Studio Pro on Windows)
19-
// 4. Cached CDN downloads (~/.mxcli/mxbuild/)
16+
// 1. Explicit path (--mxbuild-path)
17+
// 2. PATH lookup
18+
// 3. OS-specific known locations (Studio Pro on Windows)
19+
// 4. Cached CDN downloads (~/.mxcli/mxbuild/)
2020
//
2121
// Path discovery on Windows must NOT hardcode drive letters. Use environment
2222
// variables (PROGRAMFILES, PROGRAMW6432, SystemDrive) to locate install dirs.

mdl/ast/ast_entity.go

Lines changed: 31 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -33,15 +33,15 @@ func (k EntityKind) String() string {
3333

3434
// CreateEntityStmt represents: CREATE [OR MODIFY] PERSISTENT|NON-PERSISTENT ENTITY Module.Name [EXTENDS Parent] (attributes) ...
3535
type CreateEntityStmt struct {
36-
Name QualifiedName
37-
Kind EntityKind
38-
Generalization *QualifiedName // Parent entity for inheritance (e.g., System.Image)
39-
Attributes []Attribute
40-
Indexes []Index
41-
EventHandlers []EventHandlerDef // ON BEFORE/AFTER CREATE/COMMIT/DELETE/ROLLBACK CALL ...
42-
Position *Position
43-
Documentation string
44-
Comment string
36+
Name QualifiedName
37+
Kind EntityKind
38+
Generalization *QualifiedName // Parent entity for inheritance (e.g., System.Image)
39+
Attributes []Attribute
40+
Indexes []Index
41+
EventHandlers []EventHandlerDef // ON BEFORE/AFTER CREATE/COMMIT/DELETE/ROLLBACK CALL ...
42+
Position *Position
43+
Documentation string
44+
Comment string
4545
CreateOrModify bool // true for CREATE OR MODIFY
4646
}
4747

@@ -58,17 +58,17 @@ func (s *DropEntityStmt) isStatement() {}
5858
type AlterEntityOp int
5959

6060
const (
61-
AlterEntityAddAttribute AlterEntityOp = iota // ADD ATTRIBUTE / ADD COLUMN
62-
AlterEntityRenameAttribute // RENAME ATTRIBUTE / RENAME COLUMN
63-
AlterEntityModifyAttribute // MODIFY ATTRIBUTE / MODIFY COLUMN
64-
AlterEntityDropAttribute // DROP ATTRIBUTE / DROP COLUMN
65-
AlterEntitySetDocumentation // SET DOCUMENTATION
66-
AlterEntitySetComment // SET COMMENT
67-
AlterEntityAddIndex // ADD INDEX
68-
AlterEntityDropIndex // DROP INDEX
69-
AlterEntitySetPosition // SET POSITION (x, y)
70-
AlterEntityAddEventHandler // ADD EVENT HANDLER ON BEFORE/AFTER CREATE/COMMIT/DELETE/ROLLBACK CALL Mod.MF
71-
AlterEntityDropEventHandler // DROP EVENT HANDLER ON BEFORE/AFTER CREATE/COMMIT/DELETE/ROLLBACK
61+
AlterEntityAddAttribute AlterEntityOp = iota // ADD ATTRIBUTE / ADD COLUMN
62+
AlterEntityRenameAttribute // RENAME ATTRIBUTE / RENAME COLUMN
63+
AlterEntityModifyAttribute // MODIFY ATTRIBUTE / MODIFY COLUMN
64+
AlterEntityDropAttribute // DROP ATTRIBUTE / DROP COLUMN
65+
AlterEntitySetDocumentation // SET DOCUMENTATION
66+
AlterEntitySetComment // SET COMMENT
67+
AlterEntityAddIndex // ADD INDEX
68+
AlterEntityDropIndex // DROP INDEX
69+
AlterEntitySetPosition // SET POSITION (x, y)
70+
AlterEntityAddEventHandler // ADD EVENT HANDLER ON BEFORE/AFTER CREATE/COMMIT/DELETE/ROLLBACK CALL Mod.MF
71+
AlterEntityDropEventHandler // DROP EVENT HANDLER ON BEFORE/AFTER CREATE/COMMIT/DELETE/ROLLBACK
7272
)
7373

7474
// EventHandlerDef represents an event handler in CREATE/ALTER ENTITY syntax.
@@ -84,17 +84,17 @@ type EventHandlerDef struct {
8484
type AlterEntityStmt struct {
8585
Name QualifiedName
8686
Operation AlterEntityOp
87-
Attribute *Attribute // For ADD ATTRIBUTE
88-
AttributeName string // For RENAME/MODIFY/DROP ATTRIBUTE
89-
NewName string // For RENAME ATTRIBUTE
90-
DataType DataType // For MODIFY ATTRIBUTE
91-
Calculated bool // For MODIFY ATTRIBUTE with CALCULATED
92-
CalculatedMicroflow *QualifiedName // For MODIFY ATTRIBUTE with CALCULATED microflow
93-
Documentation string // For SET DOCUMENTATION
94-
Comment string // For SET COMMENT
95-
Index *Index // For ADD INDEX
96-
IndexName string // For DROP INDEX
97-
Position *Position // For SET POSITION
87+
Attribute *Attribute // For ADD ATTRIBUTE
88+
AttributeName string // For RENAME/MODIFY/DROP ATTRIBUTE
89+
NewName string // For RENAME ATTRIBUTE
90+
DataType DataType // For MODIFY ATTRIBUTE
91+
Calculated bool // For MODIFY ATTRIBUTE with CALCULATED
92+
CalculatedMicroflow *QualifiedName // For MODIFY ATTRIBUTE with CALCULATED microflow
93+
Documentation string // For SET DOCUMENTATION
94+
Comment string // For SET COMMENT
95+
Index *Index // For ADD INDEX
96+
IndexName string // For DROP INDEX
97+
Position *Position // For SET POSITION
9898
EventHandler *EventHandlerDef // For ADD/DROP EVENT HANDLER
9999
}
100100

mdl/ast/ast_microflow.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -657,11 +657,11 @@ func (s *ExportToMappingStmt) isMicroflowStatement() {}
657657

658658
// TransformJsonStmt represents: $Result = TRANSFORM $Input WITH Module.Transformer
659659
type TransformJsonStmt struct {
660-
OutputVariable string // Result string variable (without $)
661-
InputVariable string // Source JSON string variable (without $)
662-
Transformation QualifiedName // Data transformer qualified name
663-
ErrorHandling *ErrorHandlingClause // Optional ON ERROR clause
664-
Annotations *ActivityAnnotations // Optional @position, @caption, @color, @annotation
660+
OutputVariable string // Result string variable (without $)
661+
InputVariable string // Source JSON string variable (without $)
662+
Transformation QualifiedName // Data transformer qualified name
663+
ErrorHandling *ErrorHandlingClause // Optional ON ERROR clause
664+
Annotations *ActivityAnnotations // Optional @position, @caption, @color, @annotation
665665
}
666666

667667
func (s *TransformJsonStmt) isMicroflowStatement() {}

mdl/ast/ast_query.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ const (
7979
ShowImageCollections // SHOW IMAGE COLLECTIONS [IN module]
8080
ShowRestClients // SHOW REST CLIENTS [IN module]
8181
ShowPublishedRestServices // SHOW PUBLISHED REST SERVICES [IN module]
82-
ShowDataTransformers // LIST DATA TRANSFORMERS [IN module]
82+
ShowDataTransformers // LIST DATA TRANSFORMERS [IN module]
8383
ShowConstantValues // SHOW CONSTANT VALUES [IN module]
8484
ShowContractEntities // SHOW CONTRACT ENTITIES FROM Module.Service
8585
ShowContractActions // SHOW CONTRACT ACTIONS FROM Module.Service

mdl/ast/ast_rest.go

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -32,15 +32,15 @@ type RestOperationDef struct {
3232
Documentation string
3333
Method string // "GET", "POST", "PUT", "PATCH", "DELETE"
3434
Path string
35-
Parameters []RestParamDef // path parameters
36-
QueryParameters []RestParamDef // query parameters
37-
Headers []RestHeaderDef // HTTP headers
38-
BodyType string // "JSON", "FILE", "TEMPLATE", "MAPPING", "" (none)
39-
BodyVariable string // e.g. "$ItemData" or template string
40-
BodyMapping *RestMappingDef // for MAPPING body
41-
ResponseType string // "JSON", "STRING", "FILE", "STATUS", "NONE", "MAPPING"
42-
ResponseVariable string // e.g. "$CreatedItem"
43-
ResponseMapping *RestMappingDef // for MAPPING response
35+
Parameters []RestParamDef // path parameters
36+
QueryParameters []RestParamDef // query parameters
37+
Headers []RestHeaderDef // HTTP headers
38+
BodyType string // "JSON", "FILE", "TEMPLATE", "MAPPING", "" (none)
39+
BodyVariable string // e.g. "$ItemData" or template string
40+
BodyMapping *RestMappingDef // for MAPPING body
41+
ResponseType string // "JSON", "STRING", "FILE", "STATUS", "NONE", "MAPPING"
42+
ResponseVariable string // e.g. "$CreatedItem"
43+
ResponseMapping *RestMappingDef // for MAPPING response
4444
Timeout int
4545
}
4646

mdl/errors/errors.go

Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
// SPDX-License-Identifier: Apache-2.0
2+
3+
// Package mdlerrors provides structured error types for the MDL executor.
4+
//
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).
8+
// Every error preserves the original message via Error() for backward-compatible
9+
// string output — callers that only use %v or .Error() see no change.
10+
//
11+
// Only BackendError supports Unwrap — it wraps an underlying storage/IO error.
12+
// All other error types are leaf errors with no wrapped cause.
13+
package mdlerrors
14+
15+
import (
16+
"errors"
17+
"fmt"
18+
)
19+
20+
// ErrExit is a sentinel error indicating clean script/session termination.
21+
// Use errors.Is(err, ErrExit) to detect exit requests.
22+
var ErrExit = errors.New("exit")
23+
24+
// NotConnectedError indicates an operation was attempted without an active project connection.
25+
type NotConnectedError struct {
26+
// WriteMode is true when write access was required but not available.
27+
WriteMode bool
28+
msg string
29+
}
30+
31+
// NewNotConnected creates a NotConnectedError for read access.
32+
func NewNotConnected() *NotConnectedError {
33+
return &NotConnectedError{msg: "not connected to a project"}
34+
}
35+
36+
// NewNotConnectedWrite creates a NotConnectedError for write access.
37+
func NewNotConnectedWrite() *NotConnectedError {
38+
return &NotConnectedError{WriteMode: true, msg: "not connected to a project in write mode"}
39+
}
40+
41+
func (e *NotConnectedError) Error() string { return e.msg }
42+
43+
// NotFoundError indicates a named element was not found.
44+
type NotFoundError struct {
45+
// Kind is the element type (e.g. "entity", "module", "microflow").
46+
Kind string
47+
// Name is the qualified or simple name of the element.
48+
Name string
49+
msg string
50+
}
51+
52+
// NewNotFound creates a NotFoundError.
53+
func NewNotFound(kind, name string) *NotFoundError {
54+
return &NotFoundError{
55+
Kind: kind,
56+
Name: name,
57+
msg: fmt.Sprintf("%s not found: %s", kind, name),
58+
}
59+
}
60+
61+
// NewNotFoundMsg creates a NotFoundError with a custom message.
62+
func NewNotFoundMsg(kind, name, msg string) *NotFoundError {
63+
return &NotFoundError{Kind: kind, Name: name, msg: msg}
64+
}
65+
66+
func (e *NotFoundError) Error() string { return e.msg }
67+
68+
// AlreadyExistsError indicates an element already exists when creating.
69+
type AlreadyExistsError struct {
70+
// Kind is the element type.
71+
Kind string
72+
// Name is the qualified or simple name.
73+
Name string
74+
msg string
75+
}
76+
77+
// NewAlreadyExists creates an AlreadyExistsError.
78+
func NewAlreadyExists(kind, name string) *AlreadyExistsError {
79+
return &AlreadyExistsError{
80+
Kind: kind,
81+
Name: name,
82+
msg: fmt.Sprintf("%s already exists: %s", kind, name),
83+
}
84+
}
85+
86+
// NewAlreadyExistsMsg creates an AlreadyExistsError with a custom message.
87+
func NewAlreadyExistsMsg(kind, name, msg string) *AlreadyExistsError {
88+
return &AlreadyExistsError{Kind: kind, Name: name, msg: msg}
89+
}
90+
91+
func (e *AlreadyExistsError) Error() string { return e.msg }
92+
93+
// UnsupportedError indicates an unsupported operation, feature, or property.
94+
type UnsupportedError struct {
95+
// What holds the full error message describing what is unsupported
96+
// (e.g. "unsupported attribute type: Binary").
97+
What string
98+
msg string
99+
}
100+
101+
// NewUnsupported creates an UnsupportedError.
102+
func NewUnsupported(msg string) *UnsupportedError {
103+
return &UnsupportedError{What: msg, msg: msg}
104+
}
105+
106+
func (e *UnsupportedError) Error() string { return e.msg }
107+
108+
// ValidationError indicates invalid input or configuration.
109+
type ValidationError struct {
110+
msg string
111+
}
112+
113+
// NewValidation creates a ValidationError.
114+
func NewValidation(msg string) *ValidationError {
115+
return &ValidationError{msg: msg}
116+
}
117+
118+
// NewValidationf creates a ValidationError with formatted message.
119+
func NewValidationf(format string, args ...any) *ValidationError {
120+
return &ValidationError{msg: fmt.Sprintf(format, args...)}
121+
}
122+
123+
func (e *ValidationError) Error() string { return e.msg }
124+
125+
// BackendError wraps an error from the underlying storage layer (mpr/SDK).
126+
type BackendError struct {
127+
// Op describes the operation that failed (e.g. "get domain model", "write entity").
128+
Op string
129+
Err error
130+
}
131+
132+
// NewBackend creates a BackendError wrapping a cause.
133+
func NewBackend(op string, err error) *BackendError {
134+
return &BackendError{Op: op, Err: err}
135+
}
136+
137+
func (e *BackendError) Error() string {
138+
if e.Err == nil {
139+
return fmt.Sprintf("failed to %s", e.Op)
140+
}
141+
return fmt.Sprintf("failed to %s: %v", e.Op, e.Err)
142+
}
143+
144+
func (e *BackendError) Unwrap() error { return e.Err }

0 commit comments

Comments
 (0)