toString method

  1. @override
String toString()
override

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();
}