fix(sentry): resolve minified exception types on web release

This commit is contained in:
dab246
2026-03-03 11:43:45 +07:00
committed by Dat H. Pham
parent 2e8a11e7eb
commit 437c46f5ff
53 changed files with 133 additions and 109 deletions
@@ -1,12 +1,8 @@
import 'package:core/domain/exceptions/app_base_exception.dart';
import 'package:equatable/equatable.dart';
class AddressException extends AppBaseException with EquatableMixin {
class AddressException extends AppBaseException {
const AddressException(super.message);
@override
String get exceptionName => 'AddressException';
@override
List<Object?> get props => [message, exceptionName];
}
@@ -1,15 +1,20 @@
abstract class AppBaseException implements Exception {
import 'package:equatable/equatable.dart';
abstract class AppBaseException with EquatableMixin implements Exception {
final String? message;
const AppBaseException([this.message]);
@override
String toString() {
if (message != null && message!.isNotEmpty) {
if (message?.isNotEmpty == true) {
return '$exceptionName: $message';
}
return exceptionName;
}
String get exceptionName;
@override
List<Object?> get props => [message];
}
@@ -1,12 +1,7 @@
import 'package:core/domain/exceptions/app_base_exception.dart';
import 'package:equatable/equatable.dart';
abstract class DownloadFileException extends AppBaseException
with EquatableMixin {
abstract class DownloadFileException extends AppBaseException {
const DownloadFileException(super.message);
@override
List<Object?> get props => [message, exceptionName];
}
class CommonDownloadFileException extends DownloadFileException {
@@ -1,11 +1,7 @@
import 'package:core/domain/exceptions/app_base_exception.dart';
import 'package:equatable/equatable.dart';
abstract class FileException extends AppBaseException with EquatableMixin {
abstract class FileException extends AppBaseException {
const FileException(super.message);
@override
List<Object?> get props => [message, exceptionName];
}
class NotFoundFileInFolderException extends FileException {
@@ -1,14 +1,10 @@
import 'package:core/domain/exceptions/app_base_exception.dart';
import 'package:equatable/equatable.dart';
class PlatformException extends AppBaseException with EquatableMixin {
class PlatformException extends AppBaseException {
const PlatformException(super.message);
@override
String get exceptionName => 'PlatformException';
@override
List<Object?> get props => [message, exceptionName];
}
class NoSupportPlatformException extends PlatformException {
+1 -1
View File
@@ -88,7 +88,7 @@ class MailAddress with EquatableMixin {
if (postChar == '.') {
var lastChar = address[pos - 1];
if (lastChar == '@' || lastChar == '.') {
throw const AddressException('Subdomain expected before "." or duplicate "." in "address"');
throw AddressException('Subdomain expected before "." or duplicate "." in "$address"');
}
domainSB.write('.');
pos++;
+6
View File
@@ -1,6 +1,7 @@
import 'package:core/utils/application_manager.dart';
import 'package:core/utils/build_utils.dart';
import 'package:core/utils/config/env_loader.dart';
import 'package:core/utils/app_logger.dart';
import 'package:flutter_dotenv/flutter_dotenv.dart';
/// Holds configuration values for initializing Sentry.
@@ -69,6 +70,11 @@ class SentryConfig {
final appVersion = await ApplicationManager().getAppVersion();
const sentryDist = String.fromEnvironment('SENTRY_DIST');
logTrace(
'SentryConfig::load: sentryDist is $sentryDist,'
'appVersion is $appVersion',
webConsoleEnabled: true,
);
return SentryConfig(
dsn: sentryDSN,
+39 -12
View File
@@ -55,27 +55,54 @@ class SentryInitializer {
SentryEvent event,
Hint? hint,
) async {
final req = event.request;
if (req == null) return event;
event.request = _sanitizeRequest(event.request);
event.exceptions = _deminifyExceptions(event.exceptions);
final sanitizedHeaders = Map<String, String>.from(req.headers)
..removeWhere(
(k, _) => _blockedHeaderPatterns.any(
(p) => k.toLowerCase().contains(p),
),
);
return event;
}
final sanitizedRequest = SentryRequest(
static SentryRequest? _sanitizeRequest(SentryRequest? req) {
if (req == null) return null;
return SentryRequest(
url: req.url,
method: req.method,
headers: sanitizedHeaders,
headers: _sanitizeHeaders(req.headers),
queryString: req.queryString,
cookies: null,
data: null,
);
}
event.request = sanitizedRequest;
static Map<String, String> _sanitizeHeaders(Map<String, String> headers) {
return Map<String, String>.from(headers)
..removeWhere(
(key, _) => _blockedHeaderPatterns.any(
(pattern) => key.toLowerCase().contains(pattern),
),
);
}
return event;
static List<SentryException>? _deminifyExceptions(
List<SentryException>? exceptions,
) {
if (exceptions == null) return null;
return exceptions.map((e) {
if (e.type?.startsWith('minified:') == true) {
final rawValue = e.value?.trim() ?? '';
final extractedType = RegExp(r'^([A-Za-z_][A-Za-z0-9_]*)\s*:')
.firstMatch(rawValue)
?.group(1) ??
RegExp(r"Instance of '([^']+)'").firstMatch(rawValue)?.group(1);
if (extractedType != null &&
extractedType.isNotEmpty &&
extractedType != 'minified' &&
!extractedType.startsWith('minified:')) {
e.type = extractedType;
}
}
return e;
}).toList();
}
}