Skip to content

Commit c2f2495

Browse files
committed
Return error instead of passing a log_service_error function + swap order
1 parent b49cadd commit c2f2495

5 files changed

Lines changed: 275 additions & 572 deletions

File tree

birdie_snapshots/http_service_with_query_parameter_mapping.accepted

Lines changed: 30 additions & 114 deletions
Original file line numberDiff line numberDiff line change
@@ -189,10 +189,10 @@ pub type TemperatureServiceError {
189189

190190
/// Auto-generated service for TemperatureService
191191
///
192-
/// Layer 1: Core service functions (transport-agnostic)
193-
/// Layer 2: HTTP adapters (works with gleam/http)
192+
/// Layer 1: Core service functions (transport-agnostic BitArray -> Result)
193+
/// Layer 2: HTTP adapters (gleam/http types, returns Result for middleware)
194194
///
195-
/// Error types support telemetry and logging
195+
/// HTTP adapters return Result(Response, ServiceError) for middleware pattern
196196
/// Service-level errors that can occur during request processing
197197
/// These can be logged for telemetry before converting to HTTP responses
198198
pub type ServiceError {
@@ -271,185 +271,101 @@ pub fn list_temperatures_service(
271271
/// HTTP adapter for GetTemperature
272272
/// GET /v1/temperatures/{id}
273273
/// Uses gleam/http types (server-agnostic)
274+
/// Returns Result for middleware pattern
274275
pub fn http_get_temperature(
275276
req: request.Request(BitArray),
276277
handler: fn(TemperatureRequest) -> Result(TemperatureResponse, TemperatureServiceError),
277-
error_logger: fn(ServiceError) -> Nil,
278-
) -> response.Response(BitArray) {
278+
) -> Result(response.Response(BitArray), ServiceError) {
279279
// Extract request from query/path parameters
280280
case format_query_request_for_get_temperature(req) {
281281
Ok(proto_request) -> {
282282
// Encode the request to bytes for the service function
283283
let request_bytes = encode_temperature_request(proto_request)
284284
case get_temperature_service(request_bytes, handler) {
285-
Ok(response_bytes) -> {
286-
response.Response(
285+
Ok(response_bytes) ->
286+
Ok(response.Response(
287287
status: 200,
288288
headers: [#("content-type", "application/x-protobuf")],
289289
body: response_bytes,
290-
)
291-
}
292-
Error(service_error) -> {
293-
error_logger(service_error)
294-
service_error_to_http_response(service_error)
295-
}
290+
))
291+
Error(service_error) -> Error(service_error)
296292
}
297293
}
298-
Error(_) -> {
299-
let err = DecodeError("Failed to parse query parameters")
300-
error_logger(err)
301-
service_error_to_http_response(err)
302-
}
294+
Error(_) -> Error(DecodeError("Failed to parse query parameters"))
303295
}
304296
}
305297

306298
/// HTTP adapter for DeleteTemperature
307299
/// DELETE /v1/temperatures/{id}
308300
/// Uses gleam/http types (server-agnostic)
301+
/// Returns Result for middleware pattern
309302
pub fn http_delete_temperature(
310303
req: request.Request(BitArray),
311304
handler: fn(DeleteRequest) -> Result(DeleteResponse, TemperatureServiceError),
312-
error_logger: fn(ServiceError) -> Nil,
313-
) -> response.Response(BitArray) {
305+
) -> Result(response.Response(BitArray), ServiceError) {
314306
// Extract request from query/path parameters
315307
case format_query_request_for_delete_temperature(req) {
316308
Ok(proto_request) -> {
317309
// Encode the request to bytes for the service function
318310
let request_bytes = encode_delete_request(proto_request)
319311
case delete_temperature_service(request_bytes, handler) {
320-
Ok(response_bytes) -> {
321-
response.Response(
312+
Ok(response_bytes) ->
313+
Ok(response.Response(
322314
status: 200,
323315
headers: [#("content-type", "application/x-protobuf")],
324316
body: response_bytes,
325-
)
326-
}
327-
Error(service_error) -> {
328-
error_logger(service_error)
329-
service_error_to_http_response(service_error)
330-
}
317+
))
318+
Error(service_error) -> Error(service_error)
331319
}
332320
}
333-
Error(_) -> {
334-
let err = DecodeError("Failed to parse query parameters")
335-
error_logger(err)
336-
service_error_to_http_response(err)
337-
}
321+
Error(_) -> Error(DecodeError("Failed to parse query parameters"))
338322
}
339323
}
340324

341325
/// HTTP adapter for CreateTemperature
342326
/// POST /v1/temperatures
343327
/// Uses gleam/http types (server-agnostic)
328+
/// Returns Result for middleware pattern
344329
pub fn http_create_temperature(
345330
req: request.Request(BitArray),
346331
handler: fn(TemperatureRequest) -> Result(TemperatureResponse, TemperatureServiceError),
347-
error_logger: fn(ServiceError) -> Nil,
348-
) -> response.Response(BitArray) {
332+
) -> Result(response.Response(BitArray), ServiceError) {
349333
let request_bytes = req.body
350334
case create_temperature_service(request_bytes, handler) {
351-
Ok(response_bytes) -> {
352-
response.Response(
335+
Ok(response_bytes) ->
336+
Ok(response.Response(
353337
status: 200,
354338
headers: [#("content-type", "application/x-protobuf")],
355339
body: response_bytes,
356-
)
357-
}
358-
Error(service_error) -> {
359-
error_logger(service_error)
360-
service_error_to_http_response(service_error)
361-
}
340+
))
341+
Error(service_error) -> Error(service_error)
362342
}
363343
}
364344

365345
/// HTTP adapter for ListTemperatures
366346
/// GET /v1/temperatures
367347
/// Uses gleam/http types (server-agnostic)
348+
/// Returns Result for middleware pattern
368349
pub fn http_list_temperatures(
369350
req: request.Request(BitArray),
370351
handler: fn(ListRequest) -> Result(ListResponse, TemperatureServiceError),
371-
error_logger: fn(ServiceError) -> Nil,
372-
) -> response.Response(BitArray) {
352+
) -> Result(response.Response(BitArray), ServiceError) {
373353
// Extract request from query/path parameters
374354
case format_query_request_for_list_temperatures(req) {
375355
Ok(proto_request) -> {
376356
// Encode the request to bytes for the service function
377357
let request_bytes = encode_list_request(proto_request)
378358
case list_temperatures_service(request_bytes, handler) {
379-
Ok(response_bytes) -> {
380-
response.Response(
359+
Ok(response_bytes) ->
360+
Ok(response.Response(
381361
status: 200,
382362
headers: [#("content-type", "application/x-protobuf")],
383363
body: response_bytes,
384-
)
385-
}
386-
Error(service_error) -> {
387-
error_logger(service_error)
388-
service_error_to_http_response(service_error)
389-
}
364+
))
365+
Error(service_error) -> Error(service_error)
390366
}
391367
}
392-
Error(_) -> {
393-
let err = DecodeError("Failed to parse query parameters")
394-
error_logger(err)
395-
service_error_to_http_response(err)
396-
}
397-
}
398-
}
399-
/// Convert ServiceError to HTTP response
400-
/// This is used by the HTTP adapter layer
401-
fn service_error_to_http_response(error: ServiceError) -> response.Response(BitArray) {
402-
case error {
403-
DecodeError(msg) ->
404-
response.Response(
405-
status: 400,
406-
headers: [#("content-type", "text/plain")],
407-
body: <<"Bad Request: ", msg:utf8>>
408-
)
409-
HandlerError(handler_err) ->
410-
handler_error_to_http_response(handler_err)
411-
}
412-
}
413-
414-
/// Convert handler-specific errors to HTTP responses
415-
fn handler_error_to_http_response(error: TemperatureServiceError) -> response.Response(BitArray) {
416-
case error {
417-
NotFound ->
418-
response.Response(
419-
status: 404,
420-
headers: [#("content-type", "text/plain")],
421-
body: <<"Not Found":utf8>>
422-
)
423-
Unauthorized ->
424-
response.Response(
425-
status: 401,
426-
headers: [#("content-type", "text/plain"), #("www-authenticate", "Bearer")],
427-
body: <<"Unauthorized":utf8>>
428-
)
429-
BadRequest(msg) ->
430-
response.Response(
431-
status: 400,
432-
headers: [#("content-type", "text/plain")],
433-
body: <<"Bad Request: ", msg:utf8>>
434-
)
435-
InvalidRequest(msg) ->
436-
response.Response(
437-
status: 400,
438-
headers: [#("content-type", "text/plain")],
439-
body: <<"Invalid Request: ", msg:utf8>>
440-
)
441-
InternalError(msg) ->
442-
response.Response(
443-
status: 500,
444-
headers: [#("content-type", "text/plain")],
445-
body: <<"Internal Error: ", msg:utf8>>
446-
)
447-
Unavailable(msg) ->
448-
response.Response(
449-
status: 503,
450-
headers: [#("content-type", "text/plain"), #("retry-after", "60")],
451-
body: <<"Service Unavailable: ", msg:utf8>>
452-
)
368+
Error(_) -> Error(DecodeError("Failed to parse query parameters"))
453369
}
454370
}
455371
/// Map query parameters to TemperatureRequest

0 commit comments

Comments
 (0)