call method
Execute the use case with the given params.
Prefer using the call syntax: await useCase(params)
instead of: await useCase.call(params)
Returns a Result that is either:
- Success containing the result value
- Failure containing an AppFailure
Implementation
Future<Result<T, AppFailure>> call(
Params params, {
CancelToken? cancelToken,
}) async {
final startTime = DateTime.now();
final traceCtx = (
traceId: TraceObserver.instance.currentTraceId,
spanId: TraceObserver.instance.currentSpanId,
);
// Shared metadata bag — hooks can write in pre, read in success/failure
final hookMetadata = <String, dynamic>{};
HookRegistry.instance.dispatch(
HookContext(
useCaseName: '$runtimeType',
params: params,
timestamp: startTime,
traceId: traceCtx.traceId,
spanId: traceCtx.spanId,
metadata: hookMetadata,
),
HookPhase.pre,
);
try {
// Check for cancellation before starting
cancelToken?.throwIfCancelled();
final value = await execute(params, cancelToken);
logger.fine('$runtimeType completed successfully');
HookRegistry.instance.dispatch(
HookContext(
useCaseName: '$runtimeType',
params: params,
result: value,
duration: DateTime.now().difference(startTime),
timestamp: startTime,
traceId: traceCtx.traceId,
spanId: traceCtx.spanId,
metadata: hookMetadata,
),
HookPhase.success,
);
return Result.success(value);
} on CancelledException catch (e) {
logger.info('$runtimeType was cancelled: ${e.message}');
return Result.failure(CancellationFailure(e.message));
} on AppFailure catch (e) {
logger.warning('$runtimeType failed with AppFailure: $e');
FailureReporterRegistry.instance.reportFailure(
e,
stackTrace: e.stackTrace,
attributes: {'usecase': '$runtimeType'},
);
HookRegistry.instance.dispatch(
HookContext(
useCaseName: '$runtimeType',
params: params,
failure: e,
duration: DateTime.now().difference(startTime),
timestamp: startTime,
traceId: traceCtx.traceId,
spanId: traceCtx.spanId,
metadata: hookMetadata,
),
HookPhase.failure,
);
return Result.failure(e);
} catch (e, stackTrace) {
logger.severe('$runtimeType failed unexpectedly', e, stackTrace);
final failure = AppFailure.from(e, stackTrace);
FailureReporterRegistry.instance.reportFailure(
failure,
stackTrace: stackTrace,
attributes: {'usecase': '$runtimeType'},
);
HookRegistry.instance.dispatch(
HookContext(
useCaseName: '$runtimeType',
params: params,
failure: failure,
duration: DateTime.now().difference(startTime),
timestamp: startTime,
traceId: traceCtx.traceId,
spanId: traceCtx.spanId,
metadata: hookMetadata,
),
HookPhase.failure,
);
return Result.failure(failure);
}
}