Forráskód Böngészése

Null safety migration

Neeraj Gupta 2 éve
szülő
commit
84bf988de4

+ 55 - 62
lib/core/logging/super_logging.dart

@@ -1,5 +1,3 @@
-// @dart=2.9
-
 library super_logging;
 
 import 'dart:async';
@@ -8,6 +6,7 @@ import 'dart:core';
 import 'dart:io';
 
 import 'package:ente_auth/core/logging/tunneled_transport.dart';
+import 'package:ente_auth/models/typedefs.dart';
 import 'package:flutter/foundation.dart';
 import 'package:flutter/widgets.dart';
 import 'package:http/http.dart' as http;
@@ -20,8 +19,6 @@ import 'package:sentry_flutter/sentry_flutter.dart';
 import 'package:shared_preferences/shared_preferences.dart';
 import 'package:uuid/uuid.dart';
 
-typedef FutureOrVoidCallback = FutureOr<void> Function();
-
 extension SuperString on String {
   Iterable<String> chunked(int chunkSize) sync* {
     var start = 0;
@@ -40,7 +37,7 @@ extension SuperString on String {
 }
 
 extension SuperLogRecord on LogRecord {
-  String toPrettyString([String extraLines]) {
+  String toPrettyString([String? extraLines]) {
     final header = "[$loggerName] [$level] [$time]";
 
     var msg = "$header $message";
@@ -78,9 +75,9 @@ class LogConfig {
   /// ```
   ///
   /// If this is [null], Sentry logger is completely disabled (default).
-  String sentryDsn;
+  String? sentryDsn;
 
-  String tunnel;
+  String? tunnel;
 
   /// A built-in retry mechanism for sending errors to sentry.
   ///
@@ -97,7 +94,7 @@ class LogConfig {
   /// A non-empty string will be treated as an explicit path to a directory.
   ///
   /// The chosen directory can be accessed using [SuperLogging.logFile.parent].
-  String logDirPath;
+  String? logDirPath;
 
   /// The maximum number of log files inside [logDirPath].
   ///
@@ -115,12 +112,12 @@ class LogConfig {
   /// any uncaught errors during its execution will be reported.
   ///
   /// Works by using [FlutterError.onError] and [runZoned].
-  FutureOrVoidCallback body;
+  FutureOrVoidCallback? body;
 
   /// The date format for storing log files.
   ///
   /// `DateFormat('y-M-d')` by default.
-  DateFormat dateFmt;
+  DateFormat? dateFmt;
 
   String prefix;
 
@@ -144,77 +141,78 @@ class SuperLogging {
   static final $ = Logger('ente_logging');
 
   /// The current super logging configuration
-  static LogConfig config;
+  static late LogConfig config;
 
-  static SharedPreferences _preferences;
+  static late SharedPreferences _preferences;
 
   static const keyShouldReportErrors = "should_report_errors";
 
   static const keyAnonymousUserID = "anonymous_user_id";
 
-  static Future<void> main([LogConfig config]) async {
-    config ??= LogConfig();
-
-    SuperLogging.config = config;
+  static Future<void> main([LogConfig? appConfig]) async {
+    appConfig ??= LogConfig();
+    SuperLogging.config = appConfig;
 
     WidgetsFlutterBinding.ensureInitialized();
-
     _preferences = await SharedPreferences.getInstance();
 
     appVersion ??= await getAppVersion();
 
-    final loggingEnabled = config.enableInDebugMode || kReleaseMode;
+    final enable = appConfig.enableInDebugMode || kReleaseMode;
     sentryIsEnabled =
-        loggingEnabled && config.sentryDsn != null && shouldReportErrors();
-    fileIsEnabled = loggingEnabled && config.logDirPath != null;
+        enable && appConfig.sentryDsn != null && shouldReportErrors();
+    fileIsEnabled = enable && appConfig.logDirPath != null;
 
     if (fileIsEnabled) {
       await setupLogDir();
     }
-
-    Logger.root.level = Level.ALL;
-    Logger.root.onRecord.listen(onLogRecord);
-
     if (sentryIsEnabled) {
       setupSentry();
-    } else {
-      $.info("Sentry is disabled");
     }
 
-    if (!loggingEnabled) {
+    Logger.root.level = Level.ALL;
+    Logger.root.onRecord.listen(onLogRecord);
+
+    if (!enable) {
       $.info("detected debug mode; sentry & file logging disabled.");
     }
     if (fileIsEnabled) {
-      $.info("log file for today: $logFile with prefix ${config.prefix}");
+      $.info("log file for today: $logFile with prefix ${appConfig.prefix}");
+    }
+    if (sentryIsEnabled) {
+      $.info("sentry uploader started");
     }
 
-    if (config.body == null) return;
+    if (appConfig.body == null) return;
 
-    if (loggingEnabled && sentryIsEnabled) {
+    if (enable && sentryIsEnabled) {
       await SentryFlutter.init(
         (options) {
-          options.dsn = config.sentryDsn;
+          options.dsn = appConfig!.sentryDsn;
           options.httpClient = http.Client();
-          if (config.tunnel != null) {
+          if (appConfig.tunnel != null) {
             options.transport =
-                TunneledTransport(Uri.parse(config.tunnel), options);
+                TunneledTransport(Uri.parse(appConfig.tunnel!), options);
           }
         },
-        appRunner: () => config.body(),
+        appRunner: () => appConfig!.body!(),
       );
     } else {
-      await config.body();
+      await appConfig.body!();
     }
   }
 
   static void setUserID(String userID) async {
-    if (config?.sentryDsn != null) {
+    if (config.sentryDsn != null) {
       Sentry.configureScope((scope) => scope.user = SentryUser(id: userID));
       $.info("setting sentry user ID to: $userID");
     }
   }
 
-  static Future<void> _sendErrorToSentry(Object error, StackTrace stack) async {
+  static Future<void> _sendErrorToSentry(
+    Object error,
+    StackTrace? stack,
+  ) async {
     try {
       await Sentry.captureException(
         error,
@@ -230,14 +228,14 @@ class SuperLogging {
 
   static Future onLogRecord(LogRecord rec) async {
     // log misc info if it changed
-    String extraLines = "app version: '$appVersion'\n";
+    String? extraLines = "app version: '$appVersion'\n";
     if (extraLines != _lastExtraLines) {
       _lastExtraLines = extraLines;
     } else {
       extraLines = null;
     }
 
-    final str = config.prefix + " " + rec.toPrettyString(extraLines);
+    final str = (config.prefix) + " " + rec.toPrettyString(extraLines);
 
     // write to stdout
     printLog(str);
@@ -251,16 +249,8 @@ class SuperLogging {
     }
 
     // add error to sentry queue
-    if (sentryIsEnabled) {
-      if (rec.error != null) {
-        _sendErrorToSentry(rec.error, null);
-      } else if (rec.level == Level.SEVERE || rec.level == Level.SHOUT) {
-        if (rec.error != null) {
-          _sendErrorToSentry(rec.error, null);
-        } else {
-          _sendErrorToSentry(rec.message, null);
-        }
-      }
+    if (sentryIsEnabled && rec.error != null) {
+      _sendErrorToSentry(rec.error!, null);
     }
   }
 
@@ -268,12 +258,12 @@ class SuperLogging {
   static bool isFlushing = false;
 
   static void flushQueue() async {
-    if (isFlushing) {
+    if (isFlushing || logFile == null) {
       return;
     }
     isFlushing = true;
     final entry = fileQueueEntries.removeFirst();
-    await logFile.writeAsString(entry, mode: FileMode.append, flush: true);
+    await logFile!.writeAsString(entry, mode: FileMode.append, flush: true);
     isFlushing = false;
     if (fileQueueEntries.isNotEmpty) {
       flushQueue();
@@ -292,7 +282,7 @@ class SuperLogging {
   static final sentryQueueControl = StreamController<Error>();
 
   /// Whether sentry logging is currently enabled or not.
-  static bool sentryIsEnabled;
+  static bool sentryIsEnabled = false;
 
   static Future<void> setupSentry() async {
     $.info("Setting up sentry");
@@ -318,7 +308,7 @@ class SuperLogging {
 
   static bool shouldReportErrors() {
     if (_preferences.containsKey(keyShouldReportErrors)) {
-      return _preferences.getBool(keyShouldReportErrors);
+      return _preferences.getBool(keyShouldReportErrors)!;
     } else {
       return false;
     }
@@ -333,22 +323,22 @@ class SuperLogging {
       //ignore: prefer_const_constructors
       await _preferences.setString(keyAnonymousUserID, Uuid().v4());
     }
-    return _preferences.getString(keyAnonymousUserID);
+    return _preferences.getString(keyAnonymousUserID)!;
   }
 
   /// The log file currently in use.
-  static File logFile;
+  static File? logFile;
 
   /// Whether file logging is currently enabled or not.
-  static bool fileIsEnabled;
+  static bool fileIsEnabled = false;
 
   static Future<void> setupLogDir() async {
     var dirPath = config.logDirPath;
 
     // choose [logDir]
-    if (dirPath.isEmpty) {
+    if (dirPath == null || dirPath.isEmpty) {
       final root = await getExternalStorageDirectory();
-      dirPath = '${root.path}/logs';
+      dirPath = '${root!.path}/logs';
     }
 
     // create [logDir]
@@ -361,16 +351,19 @@ class SuperLogging {
     // collect all log files with valid names
     await for (final file in dir.list()) {
       try {
-        final date = config.dateFmt.parse(basename(file.path));
+        final date = config.dateFmt!.parse(basename(file.path));
         dates[file as File] = date;
         files.add(file);
       } on FormatException {}
     }
+    final nowTime = DateTime.now();
 
     // delete old log files, if [maxLogFiles] is exceeded.
     if (files.length > config.maxLogFiles) {
       // sort files based on ascending order of date (older first)
-      files.sort((a, b) => dates[a].compareTo(dates[b]));
+      files.sort(
+        (a, b) => (dates[a] ?? nowTime).compareTo((dates[b] ?? nowTime)),
+      );
 
       final extra = files.length - config.maxLogFiles;
       final toDelete = files.sublist(0, extra);
@@ -385,13 +378,13 @@ class SuperLogging {
       }
     }
 
-    logFile = File("$dirPath/${config.dateFmt.format(DateTime.now())}.txt");
+    logFile = File("$dirPath/${config.dateFmt!.format(DateTime.now())}.txt");
   }
 
   /// Current app version, obtained from package_info plugin.
   ///
   /// See: [getAppVersion]
-  static String appVersion;
+  static String? appVersion;
 
   static Future<String> getAppVersion() async {
     final pkgInfo = await PackageInfo.fromPlatform();

+ 17 - 19
lib/core/logging/tunneled_transport.dart

@@ -1,5 +1,3 @@
-// @dart=2.9
-
 import 'dart:convert';
 
 import 'package:http/http.dart';
@@ -10,9 +8,9 @@ class TunneledTransport implements Transport {
   final Uri _tunnel;
   final SentryOptions _options;
 
-  final Dsn _dsn;
+  final Dsn? _dsn;
 
-  _CredentialBuilder _credentialBuilder;
+  _CredentialBuilder? _credentialBuilder;
 
   final Map<String, String> _headers;
 
@@ -21,7 +19,7 @@ class TunneledTransport implements Transport {
   }
 
   TunneledTransport._(this._tunnel, this._options)
-      : _dsn = Dsn.parse(_options.dsn),
+      : _dsn = _options.dsn != null ? Dsn.parse(_options.dsn!) : null,
         _headers = _buildHeaders(
           _options.platformChecker.isWeb,
           _options.sdk.identifier,
@@ -34,7 +32,7 @@ class TunneledTransport implements Transport {
   }
 
   @override
-  Future<SentryId> send(SentryEnvelope envelope) async {
+  Future<SentryId?> send(SentryEnvelope envelope) async {
     final streamedRequest = await _createStreamedRequest(envelope);
     final response = await _options.httpClient
         .send(streamedRequest)
@@ -47,7 +45,7 @@ class TunneledTransport implements Transport {
         _options.logger(
           SentryLevel.error,
           'API returned an error, statusCode = ${response.statusCode}, '
-          'body = ${response.body}',
+              'body = ${response.body}',
         );
       }
       return const SentryId.empty();
@@ -66,15 +64,15 @@ class TunneledTransport implements Transport {
   }
 
   Future<StreamedRequest> _createStreamedRequest(
-    SentryEnvelope envelope,
-  ) async {
+      SentryEnvelope envelope,
+      ) async {
     final streamedRequest = StreamedRequest('POST', _tunnel);
     envelope
         .envelopeStream(_options)
         .listen(streamedRequest.sink.add)
         .onDone(streamedRequest.sink.close);
 
-    streamedRequest.headers.addAll(_credentialBuilder.configure(_headers));
+    streamedRequest.headers.addAll(_credentialBuilder!.configure(_headers));
 
     return streamedRequest;
   }
@@ -92,13 +90,13 @@ class _CredentialBuilder {
         _clock = clock;
 
   factory _CredentialBuilder(
-    Dsn dsn,
-    String sdkIdentifier,
-    ClockProvider clock,
-  ) {
+      Dsn? dsn,
+      String sdkIdentifier,
+      ClockProvider clock,
+      ) {
     final authHeader = _buildAuthHeader(
-      publicKey: dsn.publicKey,
-      secretKey: dsn.secretKey,
+      publicKey: dsn?.publicKey,
+      secretKey: dsn?.secretKey,
       sdkIdentifier: sdkIdentifier,
     );
 
@@ -106,9 +104,9 @@ class _CredentialBuilder {
   }
 
   static String _buildAuthHeader({
-    String publicKey,
-    String secretKey,
-    String sdkIdentifier,
+    String? publicKey,
+    String? secretKey,
+    String? sdkIdentifier,
   }) {
     var header = 'Sentry sentry_version=7, sentry_client=$sdkIdentifier, '
         'sentry_key=$publicKey';