Add glitchtip for centralized error logging

This commit is contained in:
2026-07-30 02:32:30 +02:00
parent 498ad68e1c
commit c210f80f27
15 changed files with 416 additions and 193 deletions
+69 -39
View File
@@ -6,6 +6,7 @@ import 'package:image_picker/image_picker.dart';
import 'package:path/path.dart' as path;
import 'package:path_provider/path_provider.dart';
import 'package:provider/provider.dart';
import 'package:sentry_flutter/sentry_flutter.dart';
import '../models/product.dart';
import '../viewmodels/product_list_view_model.dart';
@@ -52,30 +53,39 @@ class _ProductFormViewState extends State<ProductFormView> {
return;
}
final viewModel = context.read<ProductListViewModel>();
final product = await viewModel.getProductById(widget.productId!);
try {
final viewModel = context.read<ProductListViewModel>();
final product = await viewModel.getProductById(widget.productId!);
if (!mounted) return;
if (!mounted) return;
if (product == null) {
if (product == null) {
ScaffoldMessenger.of(
context,
).showSnackBar(const SnackBar(content: Text('Product not found.')));
context.go('/products');
return;
}
_existingProduct = product;
_nameController.text = product.name;
_selectedCategory = product.category;
_priceController.text = (product.priceInCents / 100).toStringAsFixed(2);
_stockController.text = product.stockQuantity.toString();
_lowStockController.text = product.lowStockThreshold.toString();
_imagePath = product.imagePath;
_hasImage = product.imagePath != null && product.imagePath!.isNotEmpty;
setState(() => _isLoading = false);
} catch (e, stack) {
Sentry.captureException(e, stackTrace: stack);
if (!mounted) return;
ScaffoldMessenger.of(
context,
).showSnackBar(const SnackBar(content: Text('Product not found.')));
).showSnackBar(SnackBar(content: Text('Could not load product: $e')));
context.go('/products');
return;
}
_existingProduct = product;
_nameController.text = product.name;
_selectedCategory = product.category;
_priceController.text = (product.priceInCents / 100).toStringAsFixed(2);
_stockController.text = product.stockQuantity.toString();
_lowStockController.text = product.lowStockThreshold.toString();
_imagePath = product.imagePath;
_hasImage = product.imagePath != null && product.imagePath!.isNotEmpty;
setState(() => _isLoading = false);
}
@override
@@ -159,29 +169,39 @@ class _ProductFormViewState extends State<ProductFormView> {
final name = _nameController.text.trim();
final category = _selectedCategory!;
final priceInCents = _parsePriceToCents(_priceController.text);
final stockQuantity = int.parse(_stockController.text);
final lowStockThreshold = int.parse(_lowStockController.text);
final stockQuantity = int.tryParse(_stockController.text) ?? 0;
final lowStockThreshold = int.tryParse(_lowStockController.text) ?? 0;
if (widget.isEditing) {
final updatedProduct = _existingProduct!.copyWith(
name: name,
category: category,
priceInCents: priceInCents,
stockQuantity: stockQuantity,
lowStockThreshold: lowStockThreshold,
imagePath: _imagePath,
);
try {
if (widget.isEditing) {
final updatedProduct = _existingProduct!.copyWith(
name: name,
category: category,
priceInCents: priceInCents,
stockQuantity: stockQuantity,
lowStockThreshold: lowStockThreshold,
imagePath: _imagePath,
);
await viewModel.updateProduct(updatedProduct);
} else {
await viewModel.addProduct(
name: name,
category: category,
priceInCents: priceInCents,
stockQuantity: stockQuantity,
lowStockThreshold: lowStockThreshold,
imagePath: _imagePath,
await viewModel.updateProduct(updatedProduct);
} else {
await viewModel.addProduct(
name: name,
category: category,
priceInCents: priceInCents,
stockQuantity: stockQuantity,
lowStockThreshold: lowStockThreshold,
imagePath: _imagePath,
);
}
} catch (e, stack) {
Sentry.captureException(e, stackTrace: stack);
if (!mounted) return;
setState(() => _isSaving = false);
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Could not save product: $e')),
);
return;
}
if (!mounted) return;
@@ -218,7 +238,17 @@ class _ProductFormViewState extends State<ProductFormView> {
if (confirmed != true) return;
final viewModel = context.read<ProductListViewModel>();
await viewModel.deleteProduct(widget.productId!);
try {
await viewModel.deleteProduct(widget.productId!);
} catch (e, stack) {
Sentry.captureException(e, stackTrace: stack);
if (!mounted) return;
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Could not delete product: $e')),
);
return;
}
if (!mounted) return;