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(),
  );

  // final exceptionType = method.exceptionType ?? (Exception).name;

  // final methodParams = getParams(
  //   method.parameters,
  //   inferredParams: {
  //     exceptionType: refer('exception'),
  //     (ExceptionCatcherContext).name: refer('context'),
  //     (ExceptionCatcherMeta).name: refer('context.meta'),
  //     (RouteEntry).name: refer('context.meta.route'),
  //   },
  // );
  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,
              ),
            ),
        ),
      )
      ..fields.add(
        Field(
          (p) => p
            ..type = refer('DI')
            ..name = 'di'
            ..modifier = FieldModifier.final$,
        ),
      )
      ..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((ExceptionCatcherContext).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'),
                          (ExceptionCatcherContext).name: refer('context'),
                          (ExceptionCatcherMeta).name: refer('context.meta'),
                          (RouteEntry).name: refer('context.meta.route'),
                        },
                      ),
                    ).code,
                    const Code('\n'),
                  ],
                ],
                const Code('\n'),
                refer('ExceptionCatcherResult')
                    .constInstanceNamed('unhandled', [])
                    .returned
                    .statement,
              ],
            ),
        ),
      ]),
  );

  return formatter(clazz);
}