handle exceptions by throwing, not with results

This commit is contained in:
2025-10-25 21:02:22 +02:00
parent d855ca4ea4
commit 1bcc5df822
5 changed files with 66 additions and 180 deletions

View File

@@ -5,7 +5,6 @@ import 'package:flutter/foundation.dart';
import 'package:http/http.dart' as http;
import 'package:logging/logging.dart';
import 'package:path_provider/path_provider.dart'; // For cache storage
import 'package:sheetless/utility.dart';
import 'sheet.dart';
@@ -16,31 +15,22 @@ class ApiClient {
ApiClient({required this.baseUrl, this.token});
Future<Result<void>> login(String username, String password) async {
Future<void> login(String username, String password) async {
log.info("Logging in...");
try {
final url = '$baseUrl/login';
final response = await http.post(
Uri.parse(url),
headers: {'Content-Type': 'application/json'},
body: jsonEncode({'email': username, 'password': password}),
);
final url = '$baseUrl/login';
final response = await http.post(
Uri.parse(url),
headers: {'Content-Type': 'application/json'},
body: jsonEncode({'email': username, 'password': password}),
);
if (response.statusCode == 200) {
token = jsonDecode(response.body);
log.info('Login successful');
return Result.ok(null);
} else {
log.warning('Login failed: ${response.statusCode}, ${response.body}');
return Result.error(
Exception(
"Response code ${response.statusCode}\nResponse: ${response.body}",
),
);
}
} on Exception catch (e) {
log.warning('Error during login', e);
return Result.error(e);
if (response.statusCode == 200) {
token = jsonDecode(response.body);
log.info('Login successful');
} else {
throw Exception(
"Failed logging in: Response code ${response.statusCode}\nResponse: ${response.body}",
);
}
}
@@ -49,27 +39,26 @@ class ApiClient {
log.info('Logged out successfully.');
}
Future<http.Response?> get(String endpoint, {bool isBinary = false}) async {
try {
final url = '$baseUrl$endpoint';
final headers = {
'Authorization': 'Bearer $token',
if (!isBinary) 'Content-Type': 'application/json',
};
Future<http.Response> get(
String endpoint, {
bool isBinary = false,
bool throwExceptionIfStatusCodeNot200 = false,
}) async {
final url = '$baseUrl$endpoint';
final headers = {
'Authorization': 'Bearer $token',
if (!isBinary) 'Content-Type': 'application/json',
};
final response = await http.get(Uri.parse(url), headers: headers);
final response = await http.get(Uri.parse(url), headers: headers);
if (response.statusCode == 200) {
return response;
} else {
log.warning(
'GET request failed: ${response.statusCode} ${response.body}',
);
}
} catch (e) {
log.warning('Error during GET request', e);
if (!throwExceptionIfStatusCodeNot200 || response.statusCode == 200) {
return response;
} else {
throw Exception(
'GET request failed: ${response.statusCode} ${response.body}',
);
}
return null;
}
Future<http.Response?> post(
@@ -130,71 +119,41 @@ class ApiClient {
}
Future<List<Sheet>> fetchSheets() async {
try {
final response = await get("/list/sheets");
final response = await get(
"/list/sheets",
throwExceptionIfStatusCodeNot200: true,
);
if (response == null) {
return List.empty();
}
if (response.statusCode == 200) {
final data = jsonDecode(response.body);
return (data as List<dynamic>)
.map((sheet) => Sheet.fromJson(sheet as Map<String, dynamic>))
.toList();
} else {
log.warning(
'Failed to fetch sheets with status: ${response.statusCode}',
);
log.info('Response: ${response.body}');
}
} catch (e) {
log.warning('Error during fetching sheets', e);
}
return List.empty();
final data = jsonDecode(response.body);
return (data as List<dynamic>)
.map((sheet) => Sheet.fromJson(sheet as Map<String, dynamic>))
.toList();
}
Future<Uint8List?> fetchPdfFileData(String sheetUuid) async {
try {
final response = await get('/sheet/pdf/$sheetUuid', isBinary: true);
Future<Uint8List> fetchPdfFileData(String sheetUuid) async {
final response = await get(
'/sheet/pdf/$sheetUuid',
isBinary: true,
throwExceptionIfStatusCodeNot200: true,
);
if (response != null && response.statusCode == 200) {
log.info("PDF downloaded");
return response.bodyBytes;
} else {
log.warning(
"Failed to fetch PDF from API. Status: ${response?.statusCode}",
);
}
} catch (e) {
log.warning("Error fetching PDF", e);
}
return null;
log.info("PDF downloaded");
return response.bodyBytes;
}
Future<File?> getPdfFileCached(String sheetUuid) async {
try {
final cacheDir = await getTemporaryDirectory();
final cachedPdfPath = '${cacheDir.path}/$sheetUuid.pdf';
Future<File> getPdfFileCached(String sheetUuid) async {
final cacheDir = await getTemporaryDirectory();
final cachedPdfPath = '${cacheDir.path}/$sheetUuid.pdf';
final cachedFile = File(cachedPdfPath);
if (await cachedFile.exists()) {
log.info("PDF found in cache: $cachedPdfPath");
return cachedFile;
}
final pdfFileData = await fetchPdfFileData(sheetUuid);
await cachedFile.writeAsBytes(
pdfFileData!,
); // TODO: proper error handling
log.info("PDF cached at: $cachedPdfPath");
final cachedFile = File(cachedPdfPath);
if (await cachedFile.exists()) {
log.info("PDF found in cache: $cachedPdfPath");
return cachedFile;
} catch (e) {
log.warning("Error fetching PDF", e);
}
return null;
final pdfFileData = await fetchPdfFileData(sheetUuid);
await cachedFile.writeAsBytes(pdfFileData);
log.info("PDF cached at: $cachedPdfPath");
return cachedFile;
}
}