Skip to content

Commit 3247e93

Browse files
committed
feat(data): add logging to data collection handler
- Add logger for GET and POST requests - Log request details and query parameters - Add error handling and logging for unsupported model types - Improve error messages for internal errors
1 parent 91217ba commit 3247e93

File tree

1 file changed

+132
-89
lines changed

1 file changed

+132
-89
lines changed

routes/api/v1/data/index.dart

Lines changed: 132 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,12 @@ import 'package:data_repository/data_repository.dart';
77
import 'package:flutter_news_app_api_server_full_source_code/src/helpers/response_helper.dart';
88
import 'package:flutter_news_app_api_server_full_source_code/src/rbac/permission_service.dart';
99
import 'package:flutter_news_app_api_server_full_source_code/src/registry/model_registry.dart';
10+
import 'package:logging/logging.dart';
1011
import 'package:mongo_dart/mongo_dart.dart';
1112

13+
// Create a logger for this file.
14+
final _logger = Logger('data_collection_handler');
15+
1216
/// Handles requests for the /api/v1/data collection endpoint.
1317
Future<Response> onRequest(RequestContext context) async {
1418
switch (context.request.method) {
@@ -28,6 +32,11 @@ Future<Response> _handleGet(RequestContext context) async {
2832
final authenticatedUser = context.read<User>();
2933
final params = context.request.uri.queryParameters;
3034

35+
_logger..info(
36+
'Handling GET collection request for model "$modelName".',
37+
)
38+
..finer('Query parameters: $params');
39+
3140
Map<String, dynamic>? filter;
3241
if (params.containsKey('filter')) {
3342
try {
@@ -59,11 +68,11 @@ Future<Response> _handleGet(RequestContext context) async {
5968

6069
final pagination =
6170
(params.containsKey('limit') || params.containsKey('cursor'))
62-
? PaginationOptions(
63-
cursor: params['cursor'],
64-
limit: int.tryParse(params['limit'] ?? ''),
65-
)
66-
: null;
71+
? PaginationOptions(
72+
cursor: params['cursor'],
73+
limit: int.tryParse(params['limit'] ?? ''),
74+
)
75+
: null;
6776

6877
final userIdForRepoCall =
6978
(modelConfig.getOwnerId != null &&
@@ -95,6 +104,10 @@ Future<Response> _handlePost(RequestContext context) async {
95104
final modelConfig = context.read<ModelConfig<dynamic>>();
96105
final authenticatedUser = context.read<User>();
97106

107+
_logger.info(
108+
'Handling POST request for model "$modelName".',
109+
);
110+
98111
final requestBody = await context.request.json() as Map<String, dynamic>?;
99112
if (requestBody == null) {
100113
throw const BadRequestException('Missing or invalid request body.');
@@ -147,54 +160,69 @@ Future<PaginatedResponse<dynamic>> _readAllItems(
147160
Map<String, dynamic>? filter,
148161
List<SortOption>? sort,
149162
PaginationOptions? pagination,
150-
) {
151-
switch (modelName) {
152-
case 'headline':
153-
return context.read<DataRepository<Headline>>().readAll(
154-
userId: userId,
155-
filter: filter,
156-
sort: sort,
157-
pagination: pagination,
158-
);
159-
case 'topic':
160-
return context.read<DataRepository<Topic>>().readAll(
161-
userId: userId,
162-
filter: filter,
163-
sort: sort,
164-
pagination: pagination,
165-
);
166-
case 'source':
167-
return context.read<DataRepository<Source>>().readAll(
168-
userId: userId,
169-
filter: filter,
170-
sort: sort,
171-
pagination: pagination,
172-
);
173-
case 'country':
174-
return context.read<DataRepository<Country>>().readAll(
175-
userId: userId,
176-
filter: filter,
177-
sort: sort,
178-
pagination: pagination,
179-
);
180-
case 'language':
181-
return context.read<DataRepository<Language>>().readAll(
182-
userId: userId,
183-
filter: filter,
184-
sort: sort,
185-
pagination: pagination,
186-
);
187-
case 'user':
188-
return context.read<DataRepository<User>>().readAll(
189-
userId: userId,
190-
filter: filter,
191-
sort: sort,
192-
pagination: pagination,
193-
);
194-
default:
195-
throw OperationFailedException(
196-
'Unsupported model type "$modelName" for GET all.',
197-
);
163+
) async {
164+
_logger.finer(
165+
'Executing _readAllItems for model "$modelName", userId: $userId.',
166+
);
167+
try {
168+
switch (modelName) {
169+
case 'headline':
170+
return await context.read<DataRepository<Headline>>().readAll(
171+
userId: userId,
172+
filter: filter,
173+
sort: sort,
174+
pagination: pagination,
175+
);
176+
case 'topic':
177+
return await context.read<DataRepository<Topic>>().readAll(
178+
userId: userId,
179+
filter: filter,
180+
sort: sort,
181+
pagination: pagination,
182+
);
183+
case 'source':
184+
return await context.read<DataRepository<Source>>().readAll(
185+
userId: userId,
186+
filter: filter,
187+
sort: sort,
188+
pagination: pagination,
189+
);
190+
case 'country':
191+
return await context.read<DataRepository<Country>>().readAll(
192+
userId: userId,
193+
filter: filter,
194+
sort: sort,
195+
pagination: pagination,
196+
);
197+
case 'language':
198+
return await context.read<DataRepository<Language>>().readAll(
199+
userId: userId,
200+
filter: filter,
201+
sort: sort,
202+
pagination: pagination,
203+
);
204+
case 'user':
205+
return await context.read<DataRepository<User>>().readAll(
206+
userId: userId,
207+
filter: filter,
208+
sort: sort,
209+
pagination: pagination,
210+
);
211+
default:
212+
_logger.warning('Unsupported model type "$modelName" for GET all.');
213+
throw OperationFailedException(
214+
'Unsupported model type "$modelName" for GET all.',
215+
);
216+
}
217+
} catch (e, s) {
218+
_logger.severe(
219+
'Unhandled exception in _readAllItems for model "$modelName".',
220+
e,
221+
s,
222+
);
223+
throw OperationFailedException(
224+
'An internal error occurred while reading the collection: $e',
225+
);
198226
}
199227
}
200228

@@ -204,41 +232,56 @@ Future<dynamic> _createItem(
204232
String modelName,
205233
dynamic itemToCreate,
206234
String? userId,
207-
) {
208-
switch (modelName) {
209-
case 'headline':
210-
return context.read<DataRepository<Headline>>().create(
211-
item: itemToCreate as Headline,
212-
userId: userId,
213-
);
214-
case 'topic':
215-
return context.read<DataRepository<Topic>>().create(
216-
item: itemToCreate as Topic,
217-
userId: userId,
218-
);
219-
case 'source':
220-
return context.read<DataRepository<Source>>().create(
221-
item: itemToCreate as Source,
222-
userId: userId,
223-
);
224-
case 'country':
225-
return context.read<DataRepository<Country>>().create(
226-
item: itemToCreate as Country,
227-
userId: userId,
228-
);
229-
case 'language':
230-
return context.read<DataRepository<Language>>().create(
231-
item: itemToCreate as Language,
232-
userId: userId,
233-
);
234-
case 'remote_config':
235-
return context.read<DataRepository<RemoteConfig>>().create(
236-
item: itemToCreate as RemoteConfig,
237-
userId: userId,
238-
);
239-
default:
240-
throw OperationFailedException(
241-
'Unsupported model type "$modelName" for POST.',
242-
);
235+
) async {
236+
_logger.finer(
237+
'Executing _createItem for model "$modelName", userId: $userId.',
238+
);
239+
try {
240+
switch (modelName) {
241+
case 'headline':
242+
return await context.read<DataRepository<Headline>>().create(
243+
item: itemToCreate as Headline,
244+
userId: userId,
245+
);
246+
case 'topic':
247+
return await context.read<DataRepository<Topic>>().create(
248+
item: itemToCreate as Topic,
249+
userId: userId,
250+
);
251+
case 'source':
252+
return await context.read<DataRepository<Source>>().create(
253+
item: itemToCreate as Source,
254+
userId: userId,
255+
);
256+
case 'country':
257+
return await context.read<DataRepository<Country>>().create(
258+
item: itemToCreate as Country,
259+
userId: userId,
260+
);
261+
case 'language':
262+
return await context.read<DataRepository<Language>>().create(
263+
item: itemToCreate as Language,
264+
userId: userId,
265+
);
266+
case 'remote_config':
267+
return await context.read<DataRepository<RemoteConfig>>().create(
268+
item: itemToCreate as RemoteConfig,
269+
userId: userId,
270+
);
271+
default:
272+
_logger.warning('Unsupported model type "$modelName" for POST.');
273+
throw OperationFailedException(
274+
'Unsupported model type "$modelName" for POST.',
275+
);
276+
}
277+
} catch (e, s) {
278+
_logger.severe(
279+
'Unhandled exception in _createItem for model "$modelName".',
280+
e,
281+
s,
282+
);
283+
throw OperationFailedException(
284+
'An internal error occurred while creating the item: $e',
285+
);
243286
}
244287
}

0 commit comments

Comments
 (0)