toString method
A string representation of this object.
Some classes have a default textual representation,
often paired with a static parse
function (like int.parse).
These classes will provide the textual representation as
their string representation.
Other classes have no meaningful textual representation
that a program will care about.
Such classes will typically override toString
to provide
useful information when inspecting the object,
mainly for debugging or logging.
Implementation
@override
String toString() {
final sb = StringBuffer();
sb.write('XMLHttpRequest (XHR) error.');
if (verbose) {
assert(() {
sb.write('\n');
for (var i = 0; i < 80; i++) {
sb.write('-');
}
sb.write('\n');
// Write key details
void addEntry(String key, String? value) {
sb.write(key.padRight(30));
sb.write(value);
sb.write('\n');
}
final parsedUrl = Uri.parse(url);
final isCrossOrigin = parsedUrl.origin != helpers.htmlWindowOrigin;
addEntry('Request method: ', method);
addEntry('Request URL: ', url);
addEntry('Origin: ', origin);
addEntry('Cross-origin: ', '$isCrossOrigin');
addEntry('browserCredentialsMode: ', '$browserCredentialsMode');
addEntry('browserResponseType: ', browserResponseType);
sb.write(
'''
THE REASON FOR THE XHR ERROR IS UNKNOWN.
(For security reasons, browsers do not explain XHR errors.)
Is the server down? Did the server have an internal error?
''',
);
// Warn about possible problem with missing CORS headers
if (isCrossOrigin) {
// List of header name that the server may need to whitelist
final sortedHeaderNames = <String>[];
headers.forEach((name, values) {
sortedHeaderNames.add(name);
});
sortedHeaderNames.sort();
if (browserCredentialsMode) {
if (method != 'HEAD' && method != 'GET') {
sb.write(
'Did the server respond to a cross-origin "preflight" (OPTIONS) request?\n'
'\n',
);
}
sb.write(
'Did the server respond with the following headers?\n'
' * Access-Control-Allow-Credentials: true\n'
' * Alternatively, disable "credentials mode".\n'
' * Access-Control-Allow-Origin: $origin\n'
' * In credentials mode, wildcard ("*") would not work!\n'
' * Access-Control-Allow-Methods: $method\n'
' * In credentials mode, wildcard ("*") would not work!\n',
);
if (sortedHeaderNames.isNotEmpty) {
final joinedHeaderNames = sortedHeaderNames.join(', ');
sb.write(
' * Access-Control-Allow-Headers: $joinedHeaderNames\n'
' * In credentials mode, wildcard ("*") would not work!\n',
);
}
} else {
sb.write("""
Enabling credentials mode would enable use of some HTTP headers in both the
request and the response. For example, credentials mode is required for
sending/receiving cookies. If you think you need to enable 'credentials mode',
do the following:
final httpClientRequest = ...;
if (httpClientRequest is BrowserHttpClientRequest) {
httpClientRequest.browserCredentialsMode = true;
}
""");
if (method != 'HEAD' && method != 'GET') {
sb.write(
'Did the server respond to a cross-origin "preflight" (OPTIONS) request?\n'
'\n',
);
}
sb.write(
'Did the server respond with the following headers?\n'
' * Access-Control-Allow-Origin: $origin\n'
' * You can also use wildcard ("*").\n'
' * Always required for cross-origin requests!\n',
);
if (!_corsSimpleMethods.contains(method)) {
sb.write(
' * Access-Control-Allow-Methods: $method\n'
' * You can also use wildcard ("*").\n',
);
}
if (sortedHeaderNames.isNotEmpty) {
final joinedHeaderNames = sortedHeaderNames.join(', ');
sb.write(
' * Access-Control-Allow-Headers: $joinedHeaderNames\n'
' * You can also use wildcard ("*").\n',
);
}
}
}
sb.write(
'\n'
'Want shorter error messages? Set the following static field:\n'
' BrowserHttpException.verbose = false;\n',
);
// Write a line
for (var i = 0; i < 80; i++) {
sb.write('-');
}
sb.write('\n');
return true;
}());
}
return sb.toString();
}