Logging data
Try-catch function
This commit is contained in:
anhtunz
2025-06-17 16:43:45 +07:00
parent 22fef0e0a8
commit 2d53f2cdd3
41 changed files with 1591 additions and 1299 deletions

View File

@@ -1,6 +1,7 @@
import 'dart:math';
import 'package:flutter/material.dart';
import 'package:sfm_app/product/utils/app_logger_utils.dart';
import 'package:sfm_app/product/utils/responsive_text_utils.dart';
import '../theme/app_theme_light.dart';
@@ -169,3 +170,15 @@ extension TextStyleExtention on BuildContext {
TextStyle get headlineLargeTextStyle =>
Theme.of(this).textTheme.headlineLarge!;
}
extension FutureExtension<T> on Future<T> {
Future<T> handleApiError() async {
try {
return await this;
} catch (e) {
AppLoggerUtils.error(e.toString());
return Future.error(e);
}
}
}

View File

@@ -2,6 +2,8 @@ import 'dart:async';
import 'dart:convert';
import 'dart:developer';
import '../utils/app_logger_utils.dart';
import '../constant/status_code/status_code_constants.dart';
import '../cache/local_manager.dart';
@@ -39,7 +41,8 @@ class NetworkManager {
Future<String> getDataFromServer(String path) async {
try {
final url = Uri.https(ApplicationConstants.DOMAIN, path);
log("[${DateTime.now().toLocal().toString().split(' ')[1]}] GET url: $url");
AppLoggerUtils.info("GET url: $url");
// log("[${DateTime.now().toLocal().toString().split(' ')[1]}] GET url: $url");
final headers = await getHeaders();
final response = await http.get(url, headers: headers).timeout(
Duration(seconds: ApplicationConstants.CALL_API_TIMEOUT),
@@ -53,7 +56,8 @@ class NetworkManager {
throw Exception('Lỗi server: ${response.statusCode}');
}
} catch (e, stackTrace) {
log('Lỗi khi lấy dữ liệu: $e, StackTrace: $stackTrace');
// AppLoggerUtils.error(message)
// log('Lỗi khi lấy dữ liệu: $e, StackTrace: $stackTrace');
throw Exception('Lỗi khi lấy dữ liệu: $e');
}
}
@@ -73,7 +77,8 @@ class NetworkManager {
String path, Map<String, dynamic> params) async {
try {
final url = Uri.https(ApplicationConstants.DOMAIN, path, params);
log("[${DateTime.now().toLocal().toString().split(' ')[1]}] GET Params url: $url");
AppLoggerUtils.info("GET Params url: $url");
// log("[${DateTime.now().toLocal().toString().split(' ')[1]}] GET Params url: $url");
final headers = await getHeaders();
final response = await http.get(url, headers: headers).timeout(
Duration(seconds: ApplicationConstants.CALL_API_TIMEOUT),
@@ -90,16 +95,16 @@ class NetworkManager {
log('Lỗi khi lấy dữ liệu: $e, StackTrace: $stackTrace');
throw Exception('Lỗi khi lấy dữ liệu: $e');
}
final url = Uri.https(ApplicationConstants.DOMAIN, path, params);
log("[${DateTime.now().toLocal().toString().split(' ')[1]}] GET Params url: $url");
final headers = await getHeaders();
final response = await http.get(url, headers: headers);
if (response.statusCode == StatusCodeConstants.CREATED ||
response.statusCode == StatusCodeConstants.OK) {
return response.body;
} else {
return "";
}
// final url = Uri.https(ApplicationConstants.DOMAIN, path, params);
// log("[${DateTime.now().toLocal().toString().split(' ')[1]}] GET Params url: $url");
// final headers = await getHeaders();
// final response = await http.get(url, headers: headers);
// if (response.statusCode == StatusCodeConstants.CREATED ||
// response.statusCode == StatusCodeConstants.OK) {
// return response.body;
// } else {
// return "";
// }
}
/// Creates new data on the server using a POST request.
@@ -109,7 +114,8 @@ class NetworkManager {
Future<int> createDataInServer(String path, Map<String, dynamic> body) async {
try {
final url = Uri.https(ApplicationConstants.DOMAIN, path);
log("[${DateTime.now().toLocal().toString().split(' ')[1]}] POST url: $url");
AppLoggerUtils.info("POST url: $url");
// log("[${DateTime.now().toLocal().toString().split(' ')[1]}] POST url: $url");
final headers = await getHeaders();
final response = await http
.post(url, headers: headers, body: jsonEncode(body))
@@ -137,7 +143,8 @@ class NetworkManager {
Future<int> updateDataInServer(String path, Map<String, dynamic> body) async {
try {
final url = Uri.https(ApplicationConstants.DOMAIN, path);
log("[${DateTime.now().toLocal().toString().split(' ')[1]}] PUT url: $url");
AppLoggerUtils.info("PUT url: $url");
// log("[${DateTime.now().toLocal().toString().split(' ')[1]}] PUT url: $url");
final headers = await getHeaders();
final response =
await http.put(url, headers: headers, body: jsonEncode(body)).timeout(
@@ -166,7 +173,8 @@ class NetworkManager {
Future<int> deleteDataInServer(String path) async {
try {
final url = Uri.https(ApplicationConstants.DOMAIN, path);
log("[${DateTime.now().toLocal().toString().split(' ')[1]}] DELETE url: $url");
// log("[${DateTime.now().toLocal().toString().split(' ')[1]}] DELETE url: $url");
AppLoggerUtils.info("DELETE url: $url");
final headers = await getHeaders();
final response = await http.delete(url, headers: headers).timeout(
Duration(seconds: ApplicationConstants.CALL_API_TIMEOUT),

View File

@@ -5,7 +5,8 @@ import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:http/http.dart' as http;
import 'package:sfm_app/product/shared/model/province_model.dart';
import '../shared/model/province_model.dart';
import '../utils/app_logger_utils.dart';
import '../../feature/device_log/device_logs_model.dart';
import '../../feature/devices/device_model.dart';
import '../../feature/home/device_alias_model.dart';
@@ -26,6 +27,8 @@ import '../constant/enums/local_keys_enums.dart';
import '../network/network_manager.dart';
class APIServices {
Map<String, String> headers = {
'Accept': 'application/json',
'Content-Type': 'application/json',
@@ -52,12 +55,10 @@ class APIServices {
return headers;
}
Future<T> executeApiCall<T>(
Future<dynamic> Function() apiCall, {
T Function(dynamic)? parser,
String errorMessage = 'Lỗi khi gọi API',
T Function(int)? statusCodeHandler, // Thêm handler cho statusCode
}) async {
Future<T> executeApiCall<T>(Future<dynamic> Function() apiCall,
{T Function(dynamic)? parser,
String errorMessage = 'Lỗi khi gọi API',
T Function(int)? statusCodeHandler}) async {
try {
final response = await apiCall().timeout(
Duration(seconds: ApplicationConstants.CALL_API_TIMEOUT),
@@ -81,11 +82,38 @@ class APIServices {
throw Exception('Dữ liệu trả về rỗng');
}
} catch (e, stackTrace) {
// log('Lỗi API: $e, StackTrace: $stackTrace');
AppLoggerUtils.error("Lỗi gọi API", e, stackTrace);
throw Exception('$errorMessage: $e');
}
}
/// Most Used Function
// Future<T> execute<T>(Future<T> Function() apiCall) async {
// try {
// return await apiCall();
// } catch (e) {
// AppLoggerUtils.error(e.toString());
// return Future.error(e);
// }
// }
Future<T> execute<T>(
BuildContext context,
Future<T> Function() apiCall, {
bool checkMounted = true,
}) async {
try {
return await apiCall();
} catch (e) {
if (checkMounted && !context.mounted) {
return Future.error('Widget not mounted');
}
showErrorTopSnackBarCustom(context, "Lỗi hệ thống");
return Future.error(e);
}
}
Future<String> login(String path, Map<String, dynamic> loginRequest) async {
final url = Uri.https(ApplicationConstants.DOMAIN, path);
final headers = await getHeaders();
@@ -229,7 +257,8 @@ class APIServices {
);
}
Future<int> updateDeviceNotificationSettings(String thingID, Map<String, int> data) async {
Future<int> updateDeviceNotificationSettings(
String thingID, Map<String, int> data) async {
Map<String, dynamic> body = {"thing_id": thingID, "notifi_settings": data};
return executeApiCall(
() => NetworkManager.instance!.updateDataInServer(
@@ -279,7 +308,7 @@ class APIServices {
.getDataFromServer(APIPathConstants.PROVINCES_PATH),
parser: (json) => Province.fromJsonDynamicList(json['items']),
errorMessage: 'Lỗi khi GET /${APIPathConstants.PROVINCES_PATH}');
;
}
Future<List<Province>> getProvincesByName(String name) async {
@@ -290,7 +319,7 @@ class APIServices {
parser: (json) => Province.fromJsonDynamicList(json['items']),
errorMessage: 'Lỗi khi GET /${APIPathConstants.PROVINCES_PATH}/$name',
);
;
}
Future<Province> getProvinceByID(String provinceID) async {

View File

@@ -0,0 +1,26 @@
import 'package:flutter/material.dart';
class SharedRocketContainer extends CustomClipper<Path> {
@override
Path getClip(Size size) {
final double width = size.width;
final double height = size.height;
const double pointyWidth = 20.0;
Path path = Path();
path.moveTo(0, 0);
path.lineTo(width - pointyWidth, 0);
path.lineTo(width, height / 2);
path.lineTo(width - pointyWidth, height);
path.lineTo(0, height);
path.close();
return path;
}
@override
bool shouldReclip(CustomClipper<Path> oldClipper) {
return false;
}
}

View File

@@ -13,6 +13,7 @@ class AppThemeDark extends AppTheme {
@override
ThemeData get theme => FlexThemeData.dark(
scaffoldBackground: Colors.black,
useMaterial3: true,
scheme: FlexScheme.flutterDash,
subThemesData: const FlexSubThemesData(

View File

@@ -13,6 +13,7 @@ class AppThemeLight extends AppTheme {
@override
ThemeData get theme => FlexThemeData.light(
scaffoldBackground: Colors.white,
useMaterial3: true,
scheme: FlexScheme.flutterDash,
bottomAppBarElevation: 20.0,

View File

@@ -0,0 +1,39 @@
import 'package:logger/logger.dart';
class AppLoggerUtils{
static final Logger _logger = Logger(
printer: PrettyPrinter(
methodCount: 2,
errorMethodCount: 8,
lineLength: 120,
colors: true,
printEmojis: true,
dateTimeFormat: (DateTime dateTime) {
// Tùy chỉnh định dạng thời gian
return '[${DateTime.now().toLocal().toString().split(' ')[1]}]';
},
// dateTimeFormat: DateTimeFormat.dateAndTime
),
level: Level.debug, // Cấp độ log tối thiểu (có thể thay đổi trong môi trường production)
);
static void debug(String message, [dynamic error, StackTrace? stackTrace]) {
_logger.d(message);
}
static void info(String message, [dynamic error, StackTrace? stackTrace]) {
_logger.i(message);
}
static void warning(String message, [dynamic error, StackTrace? stackTrace]) {
_logger.w(message, error: error, stackTrace: stackTrace);
}
static void error(String message, [dynamic error, StackTrace? stackTrace]) {
_logger.e(message, error: error, stackTrace: stackTrace);
}
static void trace(String message, [dynamic error, StackTrace? stackTrace]) {
_logger.t(message, error: error, stackTrace: stackTrace);
}
}

View File

@@ -110,7 +110,7 @@ class DeviceUtils {
String provinceID = parts[0];
String districtID = parts[1];
String wardID = parts[2];
Province province = await apiServices.getProvinceByID(provinceID);
District district = await apiServices.getDistrictByID(districtID);
Ward ward = await apiServices.getWardByID(wardID);