-
Notifications
You must be signed in to change notification settings - Fork 27.2k
/
error.dart
151 lines (123 loc) · 4.68 KB
/
error.dart
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'dart:async';
import 'dart:io' show stderr;
/// Standard error thrown by Flutter Driver API.
class DriverError extends Error {
/// Create an error with a [message] and (optionally) the [originalError] and
/// [originalStackTrace] that caused it.
DriverError(this.message, [this.originalError, this.originalStackTrace]);
/// Human-readable error message.
final String message;
/// The error object that was caught and wrapped by this error object.
final dynamic originalError;
/// The stack trace that was caught and wrapped by this error object.
final dynamic originalStackTrace;
@override
String toString() {
return '''DriverError: $message
Original error: $originalError
Original stack trace:
$originalStackTrace
''';
}
}
// Whether someone redirected the log messages somewhere.
bool _noLogSubscribers = true;
final StreamController<LogRecord> _logger =
StreamController<LogRecord>.broadcast(sync: true, onListen: () {
_noLogSubscribers = false;
});
void _log(LogLevel level, String loggerName, Object message) {
final LogRecord record = LogRecord._(level, loggerName, '$message');
// If nobody expressed interest in rerouting log messages somewhere specific,
// print them to stderr.
if (_noLogSubscribers)
stderr.writeln(record);
else
_logger.add(record);
}
/// Emits log records from Flutter Driver.
final Stream<LogRecord> flutterDriverLog = _logger.stream;
/// Severity of a log entry.
enum LogLevel {
/// Messages used to supplement the higher-level messages with more details.
///
/// This will likely produce a lot of output.
trace,
/// Informational messages that do not indicate a problem.
info,
/// A potential problem.
warning,
/// A certain problem but the program will attempt to continue.
error,
/// A critical problem; the program will attempt to quit immediately.
critical,
}
/// A log entry, as emitted on [flutterDriverLog].
class LogRecord {
const LogRecord._(this.level, this.loggerName, this.message);
/// The severity of the log record.
final LogLevel level;
/// The name of the logger that logged the message.
final String loggerName;
/// The log message.
///
/// The message should be a normal and complete sentence ending with a period.
/// It is OK to omit the subject in the message to imply [loggerName]. It is
/// also OK to omit article, such as "the" and "a".
///
/// Example: if [loggerName] is "FlutterDriver" and [message] is "Failed to
/// connect to application." then this log record means that FlutterDriver
/// failed to connect to the application.
final String message;
/// Short description of the log level.
///
/// It is meant to be read by humans. There's no guarantee that this value is
/// stable enough to be parsed by machines.
String get levelDescription => level.toString().split('.').last;
@override
String toString() => '[${levelDescription.padRight(5)}] $loggerName: $message';
}
/// Logger used internally by Flutter Driver to avoid mandating any specific
/// logging library.
///
/// By default the output from this logger is printed to [stderr]. However, a
/// subscriber to the [flutterDriverLog] stream may redirect the log records
/// elsewhere, including other logging API. The logger stops sending messages to
/// [stderr] upon first subscriber.
///
/// This class is package-private. Flutter users should use other public logging
/// libraries.
class Logger {
/// Creates a new logger.
Logger(this.name);
/// Identifies the part of the system that emits message into this object.
///
/// It is common for [name] to be used as an implicit subject of an action
/// described in a log message. For example, if you emit message "failed" and
/// [name] is "FlutterDriver", the meaning of the message should be understood
/// as "FlutterDriver failed". See also [LogRecord.message].
final String name;
/// Emits a [LogLevel.trace] record into `this` logger.
void trace(Object message) {
_log(LogLevel.trace, name, message);
}
/// Emits a [LogLevel.info] record into `this` logger.
void info(Object message) {
_log(LogLevel.info, name, message);
}
/// Emits a [LogLevel.warning] record into `this` logger.
void warning(Object message) {
_log(LogLevel.warning, name, message);
}
/// Emits a [LogLevel.error] record into `this` logger.
void error(Object message) {
_log(LogLevel.error, name, message);
}
/// Emits a [LogLevel.critical] record into `this` logger.
void critical(Object message) {
_log(LogLevel.critical, name, message);
}
}