Skip to content
Open
7 changes: 5 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,11 @@ ENV GITHUB_SHA=$GITHUB_SHA \
SENTRY_RELEASE=$SENTRY_RELEASE

RUN ./scripts/prebuild.sh && \
flutter build web --release --source-maps --dart-define=SENTRY_RELEASE=$SENTRY_RELEASE && \
if [ -n "$SENTRY_AUTH_TOKEN" ] && [ -n "$SENTRY_ORG" ] && [ -n "$SENTRY_PROJECT" ] && [ -n "$SENTRY_RELEASE" ]; then \
if [ -z "$GITHUB_SHA" ]; then echo "GITHUB_SHA is required for SENTRY_DIST"; exit 1; fi && \
flutter build web --release --source-maps \
--dart-define=SENTRY_RELEASE=$SENTRY_RELEASE \
--dart-define=SENTRY_DIST=$GITHUB_SHA && \
if [ -n "$SENTRY_AUTH_TOKEN" ] && [ -n "$SENTRY_ORG" ] && [ -n "$SENTRY_PROJECT" ] && [ -n "$SENTRY_RELEASE" ] && [ -n "$GITHUB_SHA" ]; then \
echo "Sentry configuration detected, uploading sourcemaps..." && \
curl -sL https://sentry.io/get-cli/ | SENTRY_CLI_VERSION=2.20.7 bash && \
sentry-cli releases new "$SENTRY_RELEASE" && \
Expand Down
1 change: 1 addition & 0 deletions core/lib/core.dart
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ export 'domain/exceptions/download_file_exception.dart';
export 'data/extensions/options_extensions.dart';
export 'domain/exceptions/web_session_exception.dart';
export 'domain/exceptions/platform_exception.dart';
export 'domain/exceptions/app_base_exception.dart';

// Utils
export 'presentation/utils/theme_utils.dart';
Expand Down
13 changes: 4 additions & 9 deletions core/lib/domain/exceptions/address_exception.dart
Original file line number Diff line number Diff line change
@@ -1,13 +1,8 @@
import 'package:equatable/equatable.dart';
import 'package:core/domain/exceptions/app_base_exception.dart';

class AddressException with EquatableMixin implements Exception {
final String message;

AddressException(this.message);

@override
String toString() => message;
class AddressException extends AppBaseException {
const AddressException(super.message);

@override
List<Object> get props => [message];
String get exceptionName => 'AddressException';
}
20 changes: 20 additions & 0 deletions core/lib/domain/exceptions/app_base_exception.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import 'package:equatable/equatable.dart';

abstract class AppBaseException with EquatableMixin implements Exception {
final String? message;

const AppBaseException([this.message]);

@override
String toString() {
if (message?.isNotEmpty == true) {
return '$exceptionName: $message';
}
return exceptionName;
}

String get exceptionName;

@override
List<Object?> get props => [message];
}
30 changes: 13 additions & 17 deletions core/lib/domain/exceptions/download_file_exception.dart
Original file line number Diff line number Diff line change
@@ -1,31 +1,27 @@
import 'package:equatable/equatable.dart';
import 'package:core/domain/exceptions/app_base_exception.dart';

abstract class DownloadFileException with EquatableMixin implements Exception {
final String message;

DownloadFileException(this.message);

@override
String toString() => message;

@override
List<Object> get props => [message];
abstract class DownloadFileException extends AppBaseException {
const DownloadFileException(super.message);
}

class CommonDownloadFileException extends DownloadFileException {
CommonDownloadFileException(message) : super(message);
const CommonDownloadFileException(super.message);

@override
List<Object> get props => [message];
String get exceptionName => 'CommonDownloadFileException';
}

class CancelDownloadFileException extends DownloadFileException {
CancelDownloadFileException(cancelMessage) : super(cancelMessage);
const CancelDownloadFileException(super.message);

@override
List<Object> get props => [message];
String get exceptionName => 'CancelDownloadFileException';
}

class DeviceNotSupportedException extends DownloadFileException {
DeviceNotSupportedException() : super('This device is not supported, please try on Android or iOS');
}
const DeviceNotSupportedException()
: super('This device is not supported, please try on Android or iOS');

@override
String get exceptionName => 'DeviceNotSupportedException';
}
22 changes: 10 additions & 12 deletions core/lib/domain/exceptions/file_exception.dart
Original file line number Diff line number Diff line change
@@ -1,21 +1,19 @@
import 'package:equatable/equatable.dart';
import 'package:core/domain/exceptions/app_base_exception.dart';

abstract class FileException with EquatableMixin implements Exception {
final String message;

FileException(this.message);

@override
String toString() => message;

@override
List<Object> get props => [message];
abstract class FileException extends AppBaseException {
const FileException(super.message);
}

class NotFoundFileInFolderException extends FileException {
NotFoundFileInFolderException() : super('No files found in the folder');

@override
String get exceptionName => 'NotFoundFileInFolderException';
}

class UserCancelShareFileException extends FileException {
UserCancelShareFileException() : super('User cancel share file');
}

@override
String get exceptionName => 'UserCancelShareFileException';
}
17 changes: 9 additions & 8 deletions core/lib/domain/exceptions/platform_exception.dart
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
import 'package:equatable/equatable.dart';
import 'package:core/domain/exceptions/app_base_exception.dart';

class PlatformException with EquatableMixin implements Exception {
final String message;

PlatformException(this.message);
class PlatformException extends AppBaseException {
const PlatformException(super.message);

@override
List<Object> get props => [message];
String get exceptionName => 'PlatformException';
}

class NoSupportPlatformException extends PlatformException {
NoSupportPlatformException() : super('This platform is not supported');
}
const NoSupportPlatformException() : super('This platform is not supported');

@override
String get exceptionName => 'NoSupportPlatformException';
}
18 changes: 13 additions & 5 deletions core/lib/domain/exceptions/string_exception.dart
Original file line number Diff line number Diff line change
@@ -1,7 +1,15 @@
class UnsupportedCharsetException implements Exception {
const UnsupportedCharsetException();
import 'package:core/domain/exceptions/app_base_exception.dart';

class UnsupportedCharsetException extends AppBaseException {
const UnsupportedCharsetException([super.message]);

@override
String get exceptionName => 'UnsupportedCharsetException';
}

class NullCharsetException implements Exception {
const NullCharsetException();
}
class NullCharsetException extends AppBaseException {
const NullCharsetException([super.message]);

@override
String get exceptionName => 'NullCharsetException';
}
40 changes: 28 additions & 12 deletions core/lib/domain/exceptions/web_session_exception.dart
Original file line number Diff line number Diff line change
@@ -1,28 +1,44 @@
import 'package:core/domain/exceptions/app_base_exception.dart';
import 'package:equatable/equatable.dart';

class NotFoundInWebSessionException with EquatableMixin implements Exception {
final String? errorMessage;
class NotFoundInWebSessionException extends AppBaseException
with EquatableMixin {
const NotFoundInWebSessionException({String? errorMessage})
: super(errorMessage);

NotFoundInWebSessionException({this.errorMessage});
@override
String get exceptionName => 'NotFoundInWebSessionException';

@override
List<Object> get props => [];
List<Object?> get props => [message, exceptionName];
}

class NotMatchInWebSessionException with EquatableMixin implements Exception {
const NotMatchInWebSessionException();
class NotMatchInWebSessionException extends AppBaseException
with EquatableMixin {
const NotMatchInWebSessionException() : super('Session data does not match');

@override
String get exceptionName => 'NotMatchInWebSessionException';

@override
List<Object> get props => [];
List<Object?> get props => [message, exceptionName];
}

class SaveToWebSessionFailException with EquatableMixin implements Exception {
final String? errorMessage;
class SaveToWebSessionFailException extends AppBaseException
with EquatableMixin {
const SaveToWebSessionFailException({String? errorMessage})
: super(errorMessage);

SaveToWebSessionFailException({this.errorMessage});
@override
String get exceptionName => 'SaveToWebSessionFailException';

@override
List<Object> get props => [];
List<Object?> get props => [message, exceptionName];
}

class CannotOpenNewWindowException implements Exception {}
class CannotOpenNewWindowException extends AppBaseException {
const CannotOpenNewWindowException([super.message]);

@override
String get exceptionName => 'CannotOpenNewWindowException';
}
2 changes: 1 addition & 1 deletion core/lib/utils/file_utils.dart
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ class FileUtils {

return fileDirectory;
} else {
throw DeviceNotSupportedException();
throw const DeviceNotSupportedException();
}
}

Expand Down
2 changes: 1 addition & 1 deletion core/lib/utils/logger/log_tracking.dart
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ class LogTracking {

return fileDirectory;
} else {
throw DeviceNotSupportedException();
throw const DeviceNotSupportedException();
}
}

Expand Down
14 changes: 7 additions & 7 deletions core/lib/utils/mail/mail_address.dart
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ class MailAddress with EquatableMixin {

address = address.trim();
if (address.isEmpty) {
throw AddressException('Addresses should not be empty');
throw const AddressException('Addresses should not be empty');
}
int pos = 0;

Expand Down Expand Up @@ -88,7 +88,7 @@ class MailAddress with EquatableMixin {
if (postChar == '.') {
var lastChar = address[pos - 1];
if (lastChar == '@' || lastChar == '.') {
throw AddressException('Subdomain expected before "." or duplicate "." in "address"');
throw AddressException('Subdomain expected before "." or duplicate "." in "$address"');
}
domainSB.write('.');
pos++;
Expand All @@ -113,7 +113,7 @@ class MailAddress with EquatableMixin {
if (localPart.startsWith('.') ||
localPart.endsWith('.') ||
_haveDoubleDot(localPart)) {
throw AddressException('Addresses cannot start end with "." or contain two consecutive dots');
throw const AddressException('Addresses cannot start end with "." or contain two consecutive dots');
}

domain = _createDomain(domainSB.toString());
Expand Down Expand Up @@ -409,7 +409,7 @@ class MailAddress with EquatableMixin {
lastCharDot = false;
} else if (postChar == '.') {
if (pos == 0) {
throw AddressException('Local part must not start with a "."');
throw const AddressException('Local part must not start with a "."');
}
lpSB.write('.');
pos++;
Expand Down Expand Up @@ -530,14 +530,14 @@ class MailAddress with EquatableMixin {

String localPartDetails = localPartDetailsSB.toString();
if (localPartDetails.isEmpty || localPartDetails.trim().isEmpty) {
throw AddressException("target mailbox name should not be empty");
throw const AddressException("target mailbox name should not be empty");
}
if (localPartDetails.startsWith('#')) {
throw AddressException("target mailbox name should not start with #");
throw const AddressException("target mailbox name should not start with #");
}
final forbiddenChars = RegExp(r'[*\r\n]');
if (forbiddenChars.hasMatch(localPartDetails)) {
throw AddressException("target mailbox name should not contain special characters");
throw const AddressException("target mailbox name should not contain special characters");
}

localPartSB.write(localPartDetails);
Expand Down
15 changes: 15 additions & 0 deletions core/lib/utils/sentry/sentry_config.dart
Original file line number Diff line number Diff line change
@@ -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.
Expand Down Expand Up @@ -32,6 +33,11 @@ class SentryConfig {
// Check if Sentry is available
final bool isAvailable;

// The distribution version of the release.
// In this project, it represents the Git SHA passed via `--dart-define=SENTRY_DIST`.
// This must match the `--dist` parameter used when uploading source maps to Sentry.
final String? dist;

SentryConfig({
required this.dsn,
required this.environment,
Expand All @@ -42,6 +48,7 @@ class SentryConfig {
this.isDebug = BuildUtils.isDebugMode,
this.attachScreenshot = false,
this.isAvailable = false,
this.dist,
});

/// Load configuration from an env file.
Expand All @@ -62,11 +69,19 @@ 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,
environment: sentryEnvironment,
release: appVersion,
isAvailable: isAvailable,
dist: sentryDist.isNotEmpty ? sentryDist : null,
);
}
}
Loading
Loading