Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | |
| 2 // for details. All rights reserved. Use of this source code is governed by a | |
| 3 // BSD-style license that can be found in the LICENSE file. | |
| 4 | |
| 5 library fasta.errors; | |
| 6 | |
| 7 import 'dart:async' show | |
| 8 Future; | |
| 9 | |
| 10 import 'dart:convert' show | |
| 11 JSON; | |
| 12 | |
| 13 import 'dart:io' show | |
| 14 ContentType, | |
| 15 HttpClient, | |
| 16 HttpClientRequest, | |
| 17 SocketException, | |
| 18 stderr; | |
| 19 | |
| 20 import 'colors.dart' show | |
| 21 red; | |
| 22 | |
| 23 const String defaultServerAddress = "http://127.0.0.1:59410/"; | |
| 24 | |
| 25 /// Tracks if there has been a crash reported through [reportCrash]. Should be | |
| 26 /// reset between each compilation by calling [resetCrashReporting]. | |
| 27 bool hasCrashed = false; | |
| 28 | |
| 29 /// Tracks the first source URI that has been read and is used as a fall-back | |
| 30 /// for [reportCrash]. Should be reset between each compilation by calling | |
| 31 /// [resetCrashReporting]. | |
| 32 Uri firstSourceUri; | |
| 33 | |
| 34 dynamic internalError(Object error) { | |
| 35 throw error; | |
| 36 } | |
| 37 | |
| 38 dynamic inputError(Uri uri, int charOffset, Object error) { | |
| 39 throw new InputError(uri, charOffset, error); | |
| 40 } | |
| 41 | |
| 42 class InputError { | |
| 43 final Uri uri; | |
| 44 | |
| 45 final int charOffset; | |
| 46 | |
| 47 final Object error; | |
| 48 | |
| 49 InputError(this.uri, int charOffset, this.error) | |
| 50 : this.charOffset = charOffset ?? -1; | |
| 51 | |
| 52 toString() => "InputError: $error"; | |
| 53 | |
| 54 String format() { | |
| 55 String message = red("Error: ${safeToString(error)}"); | |
|
Johnni Winther
2017/01/16 09:47:46
Should use of colors be optional. Windows command
ahe
2017/01/16 12:07:04
Yes. Added a TODO.
| |
| 56 if (uri != null) { | |
| 57 String position = charOffset == -1 ? "" : "$charOffset:"; | |
| 58 return "${uri}:$position $message"; | |
| 59 } else { | |
| 60 return message; | |
| 61 } | |
| 62 } | |
| 63 } | |
| 64 | |
| 65 class Crash { | |
| 66 final Uri uri; | |
| 67 | |
| 68 final int charOffset; | |
| 69 | |
| 70 final Object error; | |
| 71 | |
| 72 final StackTrace trace; | |
| 73 | |
| 74 Crash(this.uri, this.charOffset, this.error, this.trace); | |
| 75 | |
| 76 String toString() { | |
| 77 return """ | |
| 78 Crash when compiling $uri, | |
| 79 at character offset $charOffset: | |
| 80 $error${trace == null ? '' : '\n$trace'} | |
| 81 """; | |
| 82 } | |
| 83 } | |
| 84 | |
| 85 void resetCrashReporting() { | |
| 86 firstSourceUri = null; | |
| 87 hasCrashed = false; | |
| 88 } | |
| 89 | |
| 90 Future reportCrash(error, StackTrace trace, [Uri uri, int charOffset]) async { | |
| 91 note(String note) async { | |
| 92 stderr.write(note); | |
| 93 await stderr.flush(); | |
| 94 } | |
| 95 if (hasCrashed) return new Future.error(error, trace); | |
| 96 if (error is Crash) { | |
| 97 trace = error.trace ?? trace; | |
| 98 uri = error.uri ?? uri; | |
| 99 charOffset = error.charOffset ?? charOffset; | |
| 100 error = error.error; | |
| 101 } | |
| 102 uri ??= firstSourceUri; | |
| 103 hasCrashed = true; | |
| 104 Map<String, dynamic> data = <String, dynamic>{}; | |
| 105 data["type"] = "crash"; | |
| 106 data["client"] = "package:fasta"; | |
| 107 if (uri != null) data["uri"] = "$uri"; | |
| 108 if (charOffset != null) data["offset"] = charOffset; | |
| 109 data["error"] = safeToString(error); | |
| 110 data["trace"] = "$trace"; | |
| 111 String json = JSON.encode(data); | |
| 112 HttpClient client = new HttpClient(); | |
| 113 try { | |
| 114 Uri uri = Uri.parse(defaultServerAddress); | |
| 115 HttpClientRequest request; | |
| 116 try { | |
| 117 request = await client.postUrl(uri); | |
| 118 } on SocketException { | |
| 119 // Assume the crash logger isn't running. | |
| 120 await client.close(force: true); | |
| 121 return new Future.error(error, trace); | |
| 122 } | |
| 123 if (request != null) { | |
| 124 await note("\nSending crash report data"); | |
| 125 request.persistentConnection = false; | |
| 126 request.bufferOutput = false; | |
| 127 String host = request?.connectionInfo?.remoteAddress?.host; | |
| 128 int port = request?.connectionInfo?.remotePort; | |
| 129 await note(" to $host:$port"); | |
| 130 await request | |
| 131 ..headers.contentType = ContentType.JSON | |
| 132 ..write(json); | |
| 133 await request.close(); | |
| 134 await note("."); | |
| 135 } | |
| 136 } catch (e, s) { | |
| 137 await note("\n${safeToString(e)}\n$s\n"); | |
| 138 await note("\n\n\nFE::ERROR::$json\n\n\n"); | |
| 139 } | |
| 140 await client.close(force: true); | |
| 141 await note("\n"); | |
| 142 return new Future.error(error, trace); | |
| 143 } | |
| 144 | |
| 145 String safeToString(Object object) { | |
| 146 try { | |
| 147 return "$object"; | |
| 148 } catch (e) { | |
| 149 return "Error when converting ${object.runtimeType} to string."; | |
| 150 } | |
| 151 } | |
| OLD | NEW |