Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(169)

Side by Side Diff: pkg/telemetry/lib/crash_reporting.dart

Issue 2954733002: Add initial version of analytics and crash reporting package. (Closed)
Patch Set: update readme Created 3 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright (c) 2017, 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 import 'dart:async';
6 import 'dart:io';
7
8 import 'package:http/http.dart' as http;
9 import 'package:stack_trace/stack_trace.dart';
10 import 'package:usage/usage.dart';
11
12 /// Tells crash backend that this is a Dart error as opposed to, say, Java.
13 const String _dartTypeId = 'DartError';
14
15 /// Crash backend host.
16 const String _crashServerHost = 'clients2.google.com';
17
18 /// Path to the crash servlet.
19 const String _crashEndpointPath = '/cr/report'; // or, staging_report
20
21 /// The field corresponding to the multipart/form-data file attachment where
22 /// crash backend expects to find the Dart stack trace.
23 const String _stackTraceFileField = 'DartError';
24
25 /// The name of the file attached as [stackTraceFileField].
26 ///
27 /// The precise value is not important. It is ignored by the crash back end, but
28 /// it must be supplied in the request.
29 const String _stackTraceFilename = 'stacktrace_file';
30
31 /// Sends crash reports to Google.
Brian Wilkerson 2017/06/23 21:41:09 If we might publish this as a package someday, con
devoncarew 2017/06/26 15:53:46 Done.
32 class CrashReportSender {
kevmoo 2017/06/23 21:01:04 Should likely have a way to close/dispose this – a
devoncarew 2017/06/26 15:53:46 Good point! Added a dispose() method, doc'd it, an
33 static final Uri _baseUri = new Uri(
34 scheme: 'https',
35 host: _crashServerHost,
36 port: 443,
kevmoo 2017/06/23 21:01:04 A bit redundant w/ https?
devoncarew 2017/06/26 15:53:46 removed
37 path: _crashEndpointPath);
38
39 final Analytics analytics;
40
41 http.Client _httpClient;
kevmoo 2017/06/23 21:01:05 make final?
Brian Wilkerson 2017/06/23 21:41:09 It can't be because of the assignment on line 46.
kevmoo 2017/06/23 21:43:31 That can be done in the initializer. No worries.
devoncarew 2017/06/26 15:53:46 refactored to allow final
42
43 /// Create a new [CrashReportSender], using the data from the given
44 /// [Analytics] instance.
45 CrashReportSender(this.analytics, {http.Client httpClient}) {
46 _httpClient = httpClient ?? new http.Client();
47 }
48
49 /// Sends one crash report.
50 ///
51 /// The report is populated from data in [error] and [stackTrace].
52 Future sendReport(dynamic error, [StackTrace stackTrace]) async {
Brian Wilkerson 2017/06/23 21:41:09 Consider making stackTrace a named parameter. Addi
devoncarew 2017/06/26 15:53:46 Makes sense, will do.
53 if (!analytics.enabled) {
54 return;
55 }
56
57 try {
58 final Uri uri = _baseUri.replace(
59 queryParameters: <String, String>{
60 'product': analytics.trackingId,
61 'version': analytics.applicationVersion,
62 },
63 );
64
65 final http.MultipartRequest req = new http.MultipartRequest('POST', uri);
66 req.fields['uuid'] = analytics.clientId;
67 req.fields['product'] = analytics.trackingId;
68 req.fields['version'] = analytics.applicationVersion;
69 req.fields['osName'] = Platform.operatingSystem;
70 req.fields['osVersion'] = Platform.operatingSystem; // includes the vesion
Brian Wilkerson 2017/06/23 21:41:09 "vesion" --> "version" Should we parse out the na
devoncarew 2017/06/26 15:53:45 On investigation, this field does not contain the
71 req.fields['type'] = _dartTypeId;
72 req.fields['error_runtime_type'] = '${error.runtimeType}';
73
74 final Chain chain = new Chain.parse(stackTrace.toString());
75 req.files.add(new http.MultipartFile.fromString(
76 _stackTraceFileField, chain.terse.toString(),
77 filename: _stackTraceFilename));
78
79 final http.StreamedResponse resp = await _httpClient.send(req);
80
81 if (resp.statusCode != 200) {
82 throw 'server responded with HTTP status code ${resp.statusCode}';
83 }
84 } catch (sendError, sendStackTrace) {
kevmoo 2017/06/23 21:01:04 A tiny more conventional to use `on SocketExceptio
devoncarew 2017/06/26 15:53:45 Done.
85 if (sendError is SocketException) {
86 throw 'network error while sending crash report: $sendError';
87 } else {
88 // If the sender itself crashes, just print.
89 throw 'exception while sending crash report: $sendError\n$sendStackTrace ';
kevmoo 2017/06/23 21:01:05 long line
devoncarew 2017/06/26 15:53:46 Done.
90 }
91 }
92 }
93 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698