Update
Logging data Try-catch function
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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),
|
||||
|
||||
@@ -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 {
|
||||
|
||||
26
lib/product/shared/shared_rocket_container.dart
Normal file
26
lib/product/shared/shared_rocket_container.dart
Normal 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;
|
||||
}
|
||||
}
|
||||
@@ -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(
|
||||
|
||||
@@ -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,
|
||||
|
||||
39
lib/product/utils/app_logger_utils.dart
Normal file
39
lib/product/utils/app_logger_utils.dart
Normal 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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user