diene_problems 0.1.1 copy "diene_problems: ^0.1.1" to clipboard
diene_problems: ^0.1.1 copied to clipboard

RFC 9457 problem-details for Dart: envelope with the `data` extension, one type-URI builder, a typed registry, LocalError wrapping, and per-endpoint catalog export.

example/diene_problems_example.dart

import 'package:diene_problems/diene_problems.dart';

/// Demonstrates the clean consumer path through the public barrel alone:
/// declare problem types once, mint every `type` URI through the ONE builder,
/// and export the per-endpoint catalog the edge error portal publishes.
Future<void> main() async {
  // 1. The portal is config, never a hardcoded string (R4). A real Flutter app
  //    sources these LPSM segments from build-time `--dart-define` once
  //    `diene_config` lands; here they are literal for the sake of the example.
  const ErrorPortal portal = ErrorPortal(
    scheme: 'https',
    host: 'docs.raichu.cluster.atomi.cloud',
    landscape: 'raichu',
    platform: 'dotnet',
    service: 'user',
    module: 'api',
  );

  // 2. Register the portable generics. Domain problems stay in the service that
  //    owns them; wire ids are snake_case per R-E14.
  final ProblemRegistry registry = ProblemRegistry(portal);
  GenericProblems.registerAll(registry);

  final ProblemType notFound = registry.require('entity_not_found');
  assert(
    registry.typeUriFor(notFound) ==
        'https://docs.raichu.cluster.atomi.cloud/docs/raichu/dotnet/user/api'
            '/v1/entity_not_found',
    'the registry resolves type URIs through the single builder',
  );

  // 3. A runtime envelope round-trips through the RFC 9457 wire form.
  final Problem problem = Problem(
    type: registry.typeUriFor(notFound),
    title: notFound.title,
    status: notFound.status ?? 500,
    detail: 'User 42 does not exist',
    instance: '/user/42',
    recoverable: notFound.recoverable,
    data: const <String, Object?>{'resource': 'user', 'id': 42},
  );
  assert(
    Problem.fromJson(problem.toJson()) == problem,
    'the codec round-trips',
  );

  // 4. Any value folds into a Problem — the transformer never throws.
  final Problem folded = fromObject(<String, Object?>{
    'problemId': 'validation_error',
    'data': <String, Object?>{'fields': <Object?>[]},
  }, options: TransformOptions(portal: portal, registry: registry));
  assert(folded.status == 400, 'the registry supplied the catalogued status');

  final Problem unknown = fromObject(StateError('nothing matched'));
  assert(
    unknown.type.endsWith('/v1/$uncataloguedProblemId'),
    'an unknown value becomes an uncatalogued 5xx problem (C0 §14)',
  );

  // 5. Unexpected client-side exceptions become a LocalError Problem the
  //    flutter-base visualizer renders; production forwards captures to Faro.
  final Problem local = await LocalError(
    const NoopErrorSink(),
    portal: portal,
  ).wrap(StateError('render failed'), StackTrace.current);
  assert(local.data.containsKey('stackTrace'), 'the stack trace is carried');

  // 6. Catalog EXPORT: the producer side of the edge error portal. Each entry
  //    ships `recoverable` + `endpoints` alongside id/type/status/data, which is
  //    what the per-service × landscape Problem CR payload carries.
  final ProblemCatalog catalog = ProblemCatalog(portal: portal)
    ..addType(
      notFound,
      endpoints: const <CatalogEndpoint>[
        CatalogEndpoint(method: 'GET', path: '/user/{id}'),
      ],
    )
    ..addType(
      registry.require('validation_error'),
      endpoints: const <CatalogEndpoint>[
        CatalogEndpoint(method: 'POST', path: '/user'),
      ],
    );

  final List<Map<String, Object?>> crd = catalog.toCrdContent();
  assert(crd.length == 2, 'both problems are catalogued');
  assert(crd.first['recoverable'] == false, 'the classifier flag is exported');

  // 7. The frozen C0 contract travels with the package, so consumers can assert
  //    which authenticated release this build was projected from.
  assert(
    c0ProblemContract.provenance.releaseId.startsWith('c0-fixtures-r'),
    'the generated projection names its release',
  );
}
0
likes
160
points
1.82k
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

RFC 9457 problem-details for Dart: envelope with the `data` extension, one type-URI builder, a typed registry, LocalError wrapping, and per-endpoint catalog export.

Repository (GitHub)
View/report issues

Topics

#rfc-9457 #problem-details #errors #api

License

MIT (license)

More

Packages that depend on diene_problems