Skip to content

Commit

Permalink
feat(generator): Add ParseErrorLogger (#694)
Browse files Browse the repository at this point in the history
* feat: add error logger class

* feat: add try/catch on parsing in generator

* fix: adjust generator unit tests

* chore: adjust new tests

* fix: rename options and add missing export

* chore: fix tests
  • Loading branch information
Sadhorsephile authored Aug 13, 2024
1 parent b24d210 commit 426e6d8
Show file tree
Hide file tree
Showing 10 changed files with 682 additions and 253 deletions.
2 changes: 1 addition & 1 deletion example/lib/auth_client.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ part 'auth_client.g.dart';

@RestApi()
abstract class AuthClient {
factory AuthClient(Dio dio, {String? baseUrl}) = RestClientYmlp;
factory AuthClient(Dio dio, {String? baseUrl, ParseErrorLogger errorLogger}) = RestClientYmlp;

@POST('/api/auth/mqttClient/authentication')
Future<Object?> authenticationUsingPost({
Expand Down
2 changes: 1 addition & 1 deletion example/lib/example.dart
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ part 'example.g.dart';

@RestApi(baseUrl: 'https://5d42a6e2bc64f90014a56ca0.mockapi.io/api/v1/')
abstract class RestClient {
factory RestClient(Dio dio, {String baseUrl}) = RestClientYmlp;
factory RestClient(Dio dio, {String baseUrl, ParseErrorLogger errorLogger}) = RestClientYmlp;

@GET('/tasks/{id}')
Future<ApiResult<Task?>> getNestApiResultGenericsInnerTypeNullable();
Expand Down
2 changes: 1 addition & 1 deletion example_dartmapper/lib/example.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ part 'example.g.dart';

@RestApi(baseUrl: "https://5d42a6e2bc64f90014a56ca0.mockapi.io/api/v1/")
abstract class RestClient {
factory RestClient(Dio dio, {String baseUrl}) = _RestClient;
factory RestClient(Dio dio, {String baseUrl, ParseErrorLogger errorLogger}) = _RestClient;

@GET("/tags")
Future<List<String>> getTags();
Expand Down
2 changes: 1 addition & 1 deletion example_dartmapper/lib/json_mapper_example.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ part 'json_mapper_example.g.dart';
parser: Parser.DartJsonMapper,
)
abstract class ApiService {
factory ApiService(Dio dio, {String baseUrl}) = _ApiService;
factory ApiService(Dio dio, {String baseUrl, ParseErrorLogger errorLogger}) = _ApiService;

@GET("/tasks")
Future<List<Task>> getTasks(@Query("dateTime") DateTime dateTime);
Expand Down
2 changes: 1 addition & 1 deletion example_protobuf/lib/example.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ part 'example.g.dart';

@RestApi(baseUrl: "https://5d42a6e2bc64f90014a56ca0.mockapi.io/api/v1/")
abstract class RestClient {
factory RestClient(Dio dio, {String baseUrl}) = _RestClient;
factory RestClient(Dio dio, {String baseUrl, ParseErrorLogger errorLogger}) = _RestClient;

@POST("/tags")
Future<Result> getProtoBufInt(@Body() Params message);
Expand Down
2 changes: 1 addition & 1 deletion example_relative_base_url/lib/example.dart
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ part 'example.g.dart';

@RestApi(baseUrl: 'tasks')
abstract class TasksRestClient {
factory TasksRestClient(Dio dio, {String baseUrl}) = _TasksRestClient;
factory TasksRestClient(Dio dio, {String baseUrl, ParseErrorLogger errorLogger}) = _TasksRestClient;

@GET('/tasks/{id}')
Future<List<Task?>> getTaskById();
Expand Down
198 changes: 135 additions & 63 deletions generator/lib/src/generator.dart
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,9 @@ class RetrofitGenerator extends GeneratorForAnnotation<retrofit.RestApi> {
final RetrofitOptions globalOptions;

static const String _baseUrlVar = 'baseUrl';
static const String _errorLoggerVar = 'errorLogger';
static const _queryParamsVar = 'queryParameters';
static const _optionsVar = '_options';
static const _localHeadersVar = '_headers';
static const _headersVar = 'headers';
static const _dataVar = 'data';
Expand Down Expand Up @@ -103,7 +105,11 @@ class RetrofitGenerator extends GeneratorForAnnotation<retrofit.RestApi> {
c
..name = className
..types.addAll(element.typeParameters.map((e) => refer(e.name)))
..fields.addAll([_buildDioFiled(), _buildBaseUrlFiled(baseUrl)])
..fields.addAll([
_buildDioFiled(),
_buildBaseUrlFiled(baseUrl),
_buildErrorLoggerFiled(),
])
..constructors.addAll(
annotateClassConsts.map(
(e) => _generateConstructor(baseUrl, superClassConst: e),
Expand Down Expand Up @@ -144,6 +150,13 @@ class RetrofitGenerator extends GeneratorForAnnotation<retrofit.RestApi> {
..modifier = FieldModifier.var$;
});

Field _buildErrorLoggerFiled() => Field((m) {
m
..name = _errorLoggerVar
..type = refer('ParseErrorLogger?')
..modifier = FieldModifier.final$;
});

Constructor _generateConstructor(
String? url, {
ConstructorElement? superClassConst,
Expand All @@ -156,14 +169,20 @@ class RetrofitGenerator extends GeneratorForAnnotation<retrofit.RestApi> {
..toThis = true,
),
);
c.optionalParameters.add(
c.optionalParameters.addAll([
Parameter(
(p) => p
..named = true
..name = _baseUrlVar
..toThis = true,
),
);
Parameter(
(p) => p
..named = true
..name = _errorLoggerVar
..toThis = true,
),
]);
if (superClassConst != null) {
var superConstName = 'super';
if (superClassConst.name.isNotEmpty) {
Expand Down Expand Up @@ -534,7 +553,11 @@ class RetrofitGenerator extends GeneratorForAnnotation<retrofit.RestApi> {

final wrappedReturnType = _getResponseType(m.returnType);

final options = _parseOptions(m, namedArguments, blocks, extraOptions);
blocks.add(declareFinal(_optionsVar)
.assign(_parseOptions(m, namedArguments, blocks, extraOptions))
.statement);

final options = refer(_optionsVar).expression;

if (wrappedReturnType == null || 'void' == wrappedReturnType.toString()) {
blocks.add(
Expand Down Expand Up @@ -572,34 +595,36 @@ class RetrofitGenerator extends GeneratorForAnnotation<retrofit.RestApi> {
if (_typeChecker(List).isExactlyType(returnType) ||
_typeChecker(BuiltList).isExactlyType(returnType)) {
if (_isBasicType(innerReturnType)) {
blocks
..add(
declareFinal(_resultVar)
.assign(
refer('await $_dioVar.fetch<List<dynamic>>')
.call([options]),
blocks.add(
declareFinal(_resultVar)
.assign(
refer('await $_dioVar.fetch<List<dynamic>>').call([options]),
)
.statement,
);

_wrapInTryCatch(
blocks,
options,
returnType,
refer(_valueVar)
.assign(
refer('$_resultVar.data')
.propertyIf(
thisNullable: returnType.isNullable,
name: 'cast',
)
.statement,
)
..add(
declareFinal(_valueVar)
.assign(
refer('$_resultVar.data')
.propertyIf(
thisNullable: returnType.isNullable,
name: 'cast',
.call([], {}, [
refer(
_displayString(
innerReturnType,
withNullability: innerReturnType?.isNullable ?? false,
),
)
.call([], {}, [
refer(
_displayString(
innerReturnType,
withNullability: innerReturnType?.isNullable ?? false,
),
)
]),
)
.statement,
);
]),
)
.statement,
);
} else {
blocks.add(
declareFinal(_resultVar)
Expand All @@ -609,8 +634,11 @@ class RetrofitGenerator extends GeneratorForAnnotation<retrofit.RestApi> {
.statement,
);
if (clientAnnotation.parser == retrofit.Parser.FlutterCompute) {
blocks.add(
declareVar(_valueVar)
_wrapInTryCatch(
blocks,
options,
returnType,
refer(_valueVar)
.assign(
refer('$_resultVar.data').conditionalIsNullIf(
thisNullable: returnType.isNullable,
Expand Down Expand Up @@ -651,8 +679,12 @@ class RetrofitGenerator extends GeneratorForAnnotation<retrofit.RestApi> {
case retrofit.Parser.FlutterCompute:
throw Exception('Unreachable code');
}
blocks.add(
declareVar(_valueVar)

_wrapInTryCatch(
blocks,
options,
returnType,
refer(_valueVar)
.assign(
refer('$_resultVar.data')
.propertyIf(
Expand Down Expand Up @@ -734,8 +766,11 @@ You should create a new class to encapsulate the response.
break;
}
if (future) {
blocks.add(
declareVar(_valueVar)
_wrapInTryCatch(
blocks,
options,
returnType,
refer(_valueVar)
.assign(
refer('Map.fromEntries').call([
refer('await Future.wait').call([
Expand All @@ -747,8 +782,11 @@ You should create a new class to encapsulate the response.
.statement,
);
} else {
blocks.add(
declareVar(_valueVar)
_wrapInTryCatch(
blocks,
options,
returnType,
refer(_valueVar)
.assign(
refer('$_resultVar.data')
.propertyIf(
Expand Down Expand Up @@ -793,8 +831,11 @@ You should create a new class to encapsulate the response.
break;
}
if (future) {
blocks.add(
declareVar(_valueVar)
_wrapInTryCatch(
blocks,
options,
returnType,
refer(_valueVar)
.assign(
refer('$_resultVar.data').conditionalIsNullIf(
thisNullable: returnType.isNullable,
Expand All @@ -809,8 +850,11 @@ You should create a new class to encapsulate the response.
.statement,
);
} else {
blocks.add(
declareVar(_valueVar)
_wrapInTryCatch(
blocks,
options,
returnType,
refer(_valueVar)
.assign(
refer('$_resultVar.data')
.propertyIf(
Expand All @@ -823,8 +867,11 @@ You should create a new class to encapsulate the response.
);
}
} else {
blocks.add(
declareFinal(_valueVar)
_wrapInTryCatch(
blocks,
options,
returnType,
refer(_valueVar)
.assign(
refer('$_resultVar.data')
.propertyIf(
Expand All @@ -844,23 +891,26 @@ You should create a new class to encapsulate the response.
}
} else {
if (_isBasicType(returnType)) {
blocks
..add(
declareFinal(_resultVar)
.assign(
refer('await $_dioVar.fetch<${_displayString(returnType)}>')
.call([options]),
)
.statement,
)
..add(
declareFinal(_valueVar)
.assign(
refer('$_resultVar.data')
.asNoNullIf(returnNullable: returnType.isNullable),
)
.statement,
);
blocks.add(
declareFinal(_resultVar)
.assign(
refer('await $_dioVar.fetch<${_displayString(returnType)}>')
.call([options]),
)
.statement,
);

_wrapInTryCatch(
blocks,
options,
returnType,
refer(_valueVar)
.assign(
refer('$_resultVar.data')
.asNoNullIf(returnNullable: returnType.isNullable),
)
.statement,
);
} else if (returnType is DynamicType || returnType.isDartCoreObject) {
blocks
..add(
Expand Down Expand Up @@ -946,8 +996,11 @@ You should create a new class to encapsulate the response.
);
break;
}
blocks.add(
declareFinal(_valueVar)
_wrapInTryCatch(
blocks,
options,
returnType,
refer(_valueVar)
.assign(
refer('$_resultVar.data').conditionalIsNullIf(
thisNullable: returnType.isNullable,
Expand Down Expand Up @@ -2331,6 +2384,25 @@ ${bodyName.displayName} == null
);
}
}

void _wrapInTryCatch(
List<Code> blocks, Expression options, DartType? returnType, Code child) {
blocks.addAll(
[
declareVar(
_valueVar,
type: refer(_displayString(returnType, withNullability: true)),
late: true,
).statement,
Code('try {'),
child,
Code('} on Object catch (e, s) {'),
Code('$_errorLoggerVar?.logError(e, s, $_optionsVar);'),
Code('rethrow;'),
Code('}'),
],
);
}
}

Builder generatorFactoryBuilder(BuilderOptions options) => SharedPartBuilder(
Expand Down
Loading

0 comments on commit 426e6d8

Please sign in to comment.