exceptionContent function

String exceptionContent(
  1. ServerLifecycleComponent component,
  2. String formatter(
    1. Spec
    )
)

Implementation

String exceptionContent(
  ServerLifecycleComponent component,
  String Function(Spec) formatter,
) {
  final methods = component.exceptionCatchers;

  final (:named, :positioned) = getParams(
    component.params,
    defaultExpression: createGetFromDi(),
    useField: true,
  );

  final parameters = createConstructorParameters(component.params);
  final fields = createFields(component.params);
  final generics = createGenerics(component.genericTypes);

  final groupedMethods = groupBy(methods, (e) {
    return e.exceptionType ?? 'void';
  });

  final clazz = Class(
    (p) => p
      ..name = component.exceptionClass.className
      ..modifier = ClassModifier.final$
      ..extend = refer('${(ExceptionCatcher).name}<dynamic>')
      ..constructors.add(
        Constructor(
          (p) => p
            ..constant = true
            ..requiredParameters.add(
              Parameter(
                (p) => p
                  ..name = 'di'
                  ..toThis = true
                  ..named = false,
              ),
            )
            ..optionalParameters.addAll(parameters),
        ),
      )
      ..types.addAll(generics)
      ..fields.add(
        Field(
          (p) => p
            ..type = refer('DI')
            ..name = 'di'
            ..modifier = FieldModifier.final$,
        ),
      )
      ..fields.addAll(fields)
      ..methods.addAll([
        Method(
          (p) => p
            ..name = 'canCatch'
            ..returns = refer('bool')
            ..annotations.add(refer('override'))
            ..requiredParameters.add(
              Parameter(
                (p) => p
                  ..name = 'exception'
                  ..type = refer('Object'),
              ),
            )
            ..body = Block.of([
              for (final exception in methods)
                ifStatement(
                  refer(
                    'exception',
                  ).isA(refer(exception.exceptionType ?? 'void')),
                  body: literalTrue.returned.statement,
                ).code,
              const Code('\n'),
              literalFalse.returned.statement,
            ]),
        ),
        Method(
          (p) => p
            ..name = 'catchException'
            ..returns = refer('${(ExceptionCatcherResult).name}<dynamic>')
            ..annotations.add(refer('override'))
            ..requiredParameters.addAll([
              Parameter(
                (p) => p
                  ..name = 'exception'
                  ..type = refer('dynamic'),
              ),
              Parameter(
                (p) => p
                  ..name = 'context'
                  ..type = refer((Context).name),
              ),
            ])
            ..body = Block.of([
              declareFinal('component')
                  .assign(refer(component.name).newInstance(positioned, named))
                  .statement,
              const Code('\n'),
              ...[
                for (final MapEntry(:key, value: values)
                    in groupedMethods.entries) ...[
                  ifStatement(
                    refer('exception').isA(refer(key)),
                    body: _createComponentMethods(
                      key,
                      values,
                      inferredParams: {key: refer('exception')},
                    ),
                  ).code,
                  const Code('\n'),
                ],
              ],
              const Code('\n'),
              refer(
                'ExceptionCatcherResult',
              ).constInstanceNamed('unhandled', []).returned.statement,
            ]),
        ),
      ]),
  );

  return formatter(clazz);
}