Skip to content

Commit aefb9b6

Browse files
Merge pull request #23 from rafabene/HYPERFLEET-452
HYPERFLEET-452 - feat: implement RFC 9457 Problem Details error model
2 parents 28777bd + e813fbf commit aefb9b6

File tree

5 files changed

+315
-89
lines changed

5 files changed

+315
-89
lines changed

main.tsp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ using OpenAPI;
2020
*
2121
*/
2222
@service(#{ title: "HyperFleet API" })
23-
@info(#{ version: "1.0.2", contact: #{ name: "HyperFleet Team" }, license: #{ name: "Apache 2.0" ,url: "https://www.apache.org/licenses/LICENSE-2.0"} })
23+
@info(#{ version: "1.0.3", contact: #{ name: "HyperFleet Team" }, license: #{ name: "Apache 2.0" ,url: "https://www.apache.org/licenses/LICENSE-2.0"} })
2424
@server("https://hyperfleet.redhat.com", "Production")
2525
@route("/api/hyperfleet/v1")
2626
namespace HyperFleet;

models/common/model.tsp

Lines changed: 74 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -43,32 +43,88 @@ model ObjectReference2<Kind> {
4343
href: string;
4444
}
4545

46+
/**
47+
* Validation constraint types for field-level errors
48+
*/
49+
enum ValidationConstraint {
50+
required: "required",
51+
min: "min",
52+
max: "max",
53+
min_length: "min_length",
54+
max_length: "max_length",
55+
pattern_match: "pattern",
56+
enum_value: "enum",
57+
format_check: "format",
58+
unique: "unique",
59+
}
60+
61+
/**
62+
* Field-level validation error detail (RFC 9457 extension)
63+
*/
64+
model ValidationError {
65+
/** JSON path to the field that failed validation */
66+
@example("spec.name")
67+
field: string;
68+
69+
/** The invalid value that was provided (if safe to include) */
70+
value?: unknown;
71+
72+
/** The validation constraint that was violated */
73+
constraint?: ValidationConstraint;
74+
75+
/** Human-readable error message for this field */
76+
@example("Cluster name is required")
77+
message: string;
78+
}
79+
80+
/**
81+
* RFC 9457 Problem Details error format with HyperFleet extensions
82+
*/
4683
@defaultResponse
4784
model Error {
48-
id?: string;
85+
@header contentType: "application/problem+json";
86+
/** URI reference identifying the problem type */
87+
@format("uri")
88+
@example("https://api.hyperfleet.io/errors/validation-error")
89+
type: string;
90+
91+
/** Short human-readable summary of the problem */
92+
@example("Validation Failed")
93+
title: string;
94+
95+
/** HTTP status code */
96+
@example(400)
97+
status: int32;
98+
99+
/** Human-readable explanation specific to this occurrence */
100+
@example("The cluster name field is required")
101+
detail?: string;
102+
103+
/** URI reference for this specific occurrence */
104+
@format("uri")
105+
@example("/api/hyperfleet/v1/clusters")
106+
instance?: string;
107+
108+
/** Machine-readable error code in HYPERFLEET-CAT-NUM format */
109+
@example("HYPERFLEET-VAL-001")
110+
code?: string;
49111

50-
/** Resource kind */
51-
kind?: string;
112+
/** RFC3339 timestamp of when the error occurred */
113+
@format("date-time")
114+
@example("2024-01-15T10:30:00Z")
115+
timestamp?: string;
52116

53-
/** Resource URI */
54-
href?: string;
117+
/** Distributed trace ID for correlation */
118+
@example("abc123def456")
119+
trace_id?: string;
55120

56-
code?: string;
57-
reason?: string;
58-
operation_id?: string;
59-
60-
/** Field-level validation errors (optional) */
61-
details?: {
62-
/** Field path that failed validation */
63-
field?: string;
64-
/** Validation error message for this field */
65-
error?: string;
66-
}[];
121+
/** Field-level validation errors (for validation failures) */
122+
errors?: ValidationError[];
67123
}
68124

69-
model ErrorResponse<Kind, ErrorCode> {
70-
kind: Kind;
125+
model ErrorResponse<ErrorCode> {
71126
@statusCode statusCode: ErrorCode;
127+
@header contentType: "application/problem+json";
72128
@body error: Error;
73129
}
74130

schemas/core/openapi.yaml

Lines changed: 80 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
openapi: 3.0.0
22
info:
33
title: HyperFleet API
4-
version: 1.0.2
4+
version: 1.0.3
55
contact:
66
name: HyperFleet Team
77
license:
@@ -37,7 +37,7 @@ paths:
3737
default:
3838
description: An unexpected error response.
3939
content:
40-
application/json:
40+
application/problem+json:
4141
schema:
4242
$ref: '#/components/schemas/Error'
4343
security:
@@ -64,7 +64,7 @@ paths:
6464
default:
6565
description: An unexpected error response.
6666
content:
67-
application/json:
67+
application/problem+json:
6868
schema:
6969
$ref: '#/components/schemas/Error'
7070
requestBody:
@@ -98,7 +98,7 @@ paths:
9898
default:
9999
description: An unexpected error response.
100100
content:
101-
application/json:
101+
application/problem+json:
102102
schema:
103103
$ref: '#/components/schemas/Error'
104104
security:
@@ -132,7 +132,7 @@ paths:
132132
default:
133133
description: An unexpected error response.
134134
content:
135-
application/json:
135+
application/problem+json:
136136
schema:
137137
$ref: '#/components/schemas/Error'
138138
security:
@@ -160,7 +160,7 @@ paths:
160160
default:
161161
description: An unexpected error response.
162162
content:
163-
application/json:
163+
application/problem+json:
164164
schema:
165165
$ref: '#/components/schemas/Error'
166166
requestBody:
@@ -201,7 +201,7 @@ paths:
201201
default:
202202
description: An unexpected error response.
203203
content:
204-
application/json:
204+
application/problem+json:
205205
schema:
206206
$ref: '#/components/schemas/Error'
207207
security:
@@ -280,7 +280,7 @@ paths:
280280
default:
281281
description: An unexpected error response.
282282
content:
283-
application/json:
283+
application/problem+json:
284284
schema:
285285
$ref: '#/components/schemas/Error'
286286
/api/hyperfleet/v1/clusters/{cluster_id}/statuses:
@@ -373,7 +373,7 @@ paths:
373373
default:
374374
description: An unexpected error response.
375375
content:
376-
application/json:
376+
application/problem+json:
377377
schema:
378378
$ref: '#/components/schemas/Error'
379379
security:
@@ -916,33 +916,53 @@ components:
916916
description: Status value for conditions
917917
Error:
918918
type: object
919+
required:
920+
- type
921+
- title
922+
- status
919923
properties:
920-
id:
924+
type:
921925
type: string
922-
kind:
926+
format: uri
927+
description: URI reference identifying the problem type
928+
example: https://api.hyperfleet.io/errors/validation-error
929+
title:
923930
type: string
924-
description: Resource kind
925-
href:
931+
description: Short human-readable summary of the problem
932+
example: Validation Failed
933+
status:
934+
type: integer
935+
format: int32
936+
description: HTTP status code
937+
example: 400
938+
detail:
926939
type: string
927-
description: Resource URI
940+
description: Human-readable explanation specific to this occurrence
941+
example: The cluster name field is required
942+
instance:
943+
type: string
944+
format: uri
945+
description: URI reference for this specific occurrence
946+
example: /api/hyperfleet/v1/clusters
928947
code:
929948
type: string
930-
reason:
949+
description: Machine-readable error code in HYPERFLEET-CAT-NUM format
950+
example: HYPERFLEET-VAL-001
951+
timestamp:
931952
type: string
932-
operation_id:
953+
format: date-time
954+
description: RFC3339 timestamp of when the error occurred
955+
example: '2024-01-15T10:30:00Z'
956+
trace_id:
933957
type: string
934-
details:
958+
description: Distributed trace ID for correlation
959+
example: abc123def456
960+
errors:
935961
type: array
936962
items:
937-
type: object
938-
properties:
939-
field:
940-
type: string
941-
description: Field path that failed validation
942-
error:
943-
type: string
944-
description: Validation error message for this field
945-
description: Field-level validation errors (optional)
963+
$ref: '#/components/schemas/ValidationError'
964+
description: Field-level validation errors (for validation failures)
965+
description: RFC 9457 Problem Details error format with HyperFleet extensions
946966
NodePool:
947967
type: object
948968
required:
@@ -1269,6 +1289,40 @@ components:
12691289
- Ready
12701290
- Failed
12711291
description: Phase of a resource (Cluster or NodePool)
1292+
ValidationConstraint:
1293+
type: string
1294+
enum:
1295+
- required
1296+
- min
1297+
- max
1298+
- min_length
1299+
- max_length
1300+
- pattern
1301+
- enum
1302+
- format
1303+
- unique
1304+
description: Validation constraint types for field-level errors
1305+
ValidationError:
1306+
type: object
1307+
required:
1308+
- field
1309+
- message
1310+
properties:
1311+
field:
1312+
type: string
1313+
description: JSON path to the field that failed validation
1314+
example: spec.name
1315+
value:
1316+
description: The invalid value that was provided (if safe to include)
1317+
constraint:
1318+
allOf:
1319+
- $ref: '#/components/schemas/ValidationConstraint'
1320+
description: The validation constraint that was violated
1321+
message:
1322+
type: string
1323+
description: Human-readable error message for this field
1324+
example: Cluster name is required
1325+
description: Field-level validation error detail (RFC 9457 extension)
12721326
securitySchemes:
12731327
BearerAuth:
12741328
type: http

0 commit comments

Comments
 (0)