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

Side by Side Diff: sdk/lib/_internal/pub/lib/src/io.dart

Issue 68493003: Ensure that errors have stack traces attached. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 years, 1 month 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 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. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 /// Helper functionality to make working with IO easier. 5 /// Helper functionality to make working with IO easier.
6 library pub.io; 6 library pub.io;
7 7
8 import 'dart:async'; 8 import 'dart:async';
9 import 'dart:collection'; 9 import 'dart:collection';
10 import 'dart:convert'; 10 import 'dart:convert';
11 import 'dart:io'; 11 import 'dart:io';
12 12
13 import 'package:path/path.dart' as path; 13 import 'package:path/path.dart' as path;
14 import 'package:http/http.dart' show ByteStream; 14 import 'package:http/http.dart' show ByteStream;
15 import 'package:stack_trace/stack_trace.dart';
16
15 import 'error_group.dart'; 17 import 'error_group.dart';
16 import 'log.dart' as log; 18 import 'log.dart' as log;
17 import 'sdk.dart' as sdk; 19 import 'sdk.dart' as sdk;
18 import 'utils.dart'; 20 import 'utils.dart';
19 21
20 export 'package:http/http.dart' show ByteStream; 22 export 'package:http/http.dart' show ByteStream;
21 23
22 /// Returns whether or not [entry] is nested somewhere within [dir]. This just 24 /// Returns whether or not [entry] is nested somewhere within [dir]. This just
23 /// performs a path comparison; it doesn't look at the actual filesystem. 25 /// performs a path comparison; it doesn't look at the actual filesystem.
24 bool isBeneath(String entry, String dir) { 26 bool isBeneath(String entry, String dir) {
(...skipping 430 matching lines...) Expand 10 before | Expand all | Expand 10 after
455 /// true. 457 /// true.
456 /// 458 ///
457 /// When an error occurs on [stream], that error is passed to [sink]. If 459 /// When an error occurs on [stream], that error is passed to [sink]. If
458 /// [cancelOnError] is true, [Future] will be completed successfully and no 460 /// [cancelOnError] is true, [Future] will be completed successfully and no
459 /// more data or errors will be piped from [stream] to [sink]. If 461 /// more data or errors will be piped from [stream] to [sink]. If
460 /// [cancelOnError] and [closeSink] are both true, [sink] will then be 462 /// [cancelOnError] and [closeSink] are both true, [sink] will then be
461 /// closed. 463 /// closed.
462 Future store(Stream stream, EventSink sink, 464 Future store(Stream stream, EventSink sink,
463 {bool cancelOnError: true, bool closeSink: true}) { 465 {bool cancelOnError: true, bool closeSink: true}) {
464 var completer = new Completer(); 466 var completer = new Completer();
465 stream.listen(sink.add, 467 stream.listen(sink.add, onError: (e, stackTrace) {
466 onError: (e, [stackTrace]) { 468 sink.addError(e, stackTrace);
467 // TODO(floitsch): Sink.addError without stack trace. 469 if (cancelOnError) {
468 sink.addError(e); 470 completer.complete();
469 if (cancelOnError) { 471 if (closeSink) sink.close();
470 completer.complete(); 472 }
471 if (closeSink) sink.close(); 473 }, onDone: () {
472 } 474 if (closeSink) sink.close();
473 }, 475 completer.complete();
474 onDone: () { 476 }, cancelOnError: cancelOnError);
475 if (closeSink) sink.close();
476 completer.complete();
477 }, cancelOnError: cancelOnError);
478 return completer.future; 477 return completer.future;
479 } 478 }
480 479
481 /// Spawns and runs the process located at [executable], passing in [args]. 480 /// Spawns and runs the process located at [executable], passing in [args].
482 /// Returns a [Future] that will complete with the results of the process after 481 /// Returns a [Future] that will complete with the results of the process after
483 /// it has ended. 482 /// it has ended.
484 /// 483 ///
485 /// The spawned process will inherit its parent's environment variables. If 484 /// The spawned process will inherit its parent's environment variables. If
486 /// [environment] is provided, that will be used to augment (not replace) the 485 /// [environment] is provided, that will be used to augment (not replace) the
487 /// the inherited variables. 486 /// the inherited variables.
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after
627 /// However, if [milliseconds] pass before [input] has completed, it completes 626 /// However, if [milliseconds] pass before [input] has completed, it completes
628 /// with a [TimeoutException] with [description] (which should be a fragment 627 /// with a [TimeoutException] with [description] (which should be a fragment
629 /// describing the action that timed out). 628 /// describing the action that timed out).
630 /// 629 ///
631 /// Note that timing out will not cancel the asynchronous operation behind 630 /// Note that timing out will not cancel the asynchronous operation behind
632 /// [input]. 631 /// [input].
633 Future timeout(Future input, int milliseconds, String description) { 632 Future timeout(Future input, int milliseconds, String description) {
634 var completer = new Completer(); 633 var completer = new Completer();
635 var timer = new Timer(new Duration(milliseconds: milliseconds), () { 634 var timer = new Timer(new Duration(milliseconds: milliseconds), () {
636 completer.completeError(new TimeoutException( 635 completer.completeError(new TimeoutException(
637 'Timed out while $description.')); 636 'Timed out while $description.'),
637 new Trace.current());
638 }); 638 });
639 input.then((value) { 639 input.then((value) {
640 if (completer.isCompleted) return; 640 if (completer.isCompleted) return;
641 timer.cancel(); 641 timer.cancel();
642 completer.complete(value); 642 completer.complete(value);
643 }).catchError((e) { 643 }).catchError((e, stackTrace) {
644 if (completer.isCompleted) return; 644 if (completer.isCompleted) return;
645 timer.cancel(); 645 timer.cancel();
646 completer.completeError(e); 646 completer.completeError(e, stackTrace);
647 }); 647 });
648 return completer.future; 648 return completer.future;
649 } 649 }
650 650
651 /// Creates a temporary directory and passes its path to [fn]. Once the [Future] 651 /// Creates a temporary directory and passes its path to [fn]. Once the [Future]
652 /// returned by [fn] completes, the temporary directory and all its contents 652 /// returned by [fn] completes, the temporary directory and all its contents
653 /// will be deleted. [fn] can also return `null`, in which case the temporary 653 /// will be deleted. [fn] can also return `null`, in which case the temporary
654 /// directory is deleted immediately afterwards. 654 /// directory is deleted immediately afterwards.
655 /// 655 ///
656 /// Returns a future that completes to the value that the future returned from 656 /// Returns a future that completes to the value that the future returned from
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
768 }).toList(); 768 }).toList();
769 769
770 if (Platform.operatingSystem != "windows") { 770 if (Platform.operatingSystem != "windows") {
771 var args = ["--create", "--gzip", "--directory", baseDir]; 771 var args = ["--create", "--gzip", "--directory", baseDir];
772 args.addAll(contents); 772 args.addAll(contents);
773 // TODO(nweiz): It's possible that enough command-line arguments will make 773 // TODO(nweiz): It's possible that enough command-line arguments will make
774 // the process choke, so at some point we should save the arguments to a 774 // the process choke, so at some point we should save the arguments to a
775 // file and pass them in via --files-from for tar and -i@filename for 7zip. 775 // file and pass them in via --files-from for tar and -i@filename for 7zip.
776 startProcess("tar", args).then((process) { 776 startProcess("tar", args).then((process) {
777 store(process.stdout, controller); 777 store(process.stdout, controller);
778 }).catchError((e) { 778 }).catchError((e, stackTrace) {
779 // We don't have to worry about double-signaling here, since the store() 779 // We don't have to worry about double-signaling here, since the store()
780 // above will only be reached if startProcess succeeds. 780 // above will only be reached if startProcess succeeds.
781 controller.addError(e); 781 controller.addError(e, stackTrace);
782 controller.close(); 782 controller.close();
783 }); 783 });
784 return new ByteStream(controller.stream); 784 return new ByteStream(controller.stream);
785 } 785 }
786 786
787 withTempDir((tempDir) { 787 withTempDir((tempDir) {
788 // Create the tar file. 788 // Create the tar file.
789 var tarFile = path.join(tempDir, "intermediate.tar"); 789 var tarFile = path.join(tempDir, "intermediate.tar");
790 var args = ["a", "-w$baseDir", tarFile]; 790 var args = ["a", "-w$baseDir", tarFile];
791 args.addAll(contents.map((entry) => '-i!$entry')); 791 args.addAll(contents.map((entry) => '-i!$entry'));
792 792
793 // We're passing 'baseDir' both as '-w' and setting it as the working 793 // We're passing 'baseDir' both as '-w' and setting it as the working
794 // directory explicitly here intentionally. The former ensures that the 794 // directory explicitly here intentionally. The former ensures that the
795 // files added to the archive have the correct relative path in the archive. 795 // files added to the archive have the correct relative path in the archive.
796 // The latter enables relative paths in the "-i" args to be resolved. 796 // The latter enables relative paths in the "-i" args to be resolved.
797 return runProcess(pathTo7zip, args, workingDir: baseDir).then((_) { 797 return runProcess(pathTo7zip, args, workingDir: baseDir).then((_) {
798 // GZIP it. 7zip doesn't support doing both as a single operation. Send 798 // GZIP it. 7zip doesn't support doing both as a single operation. Send
799 // the output to stdout. 799 // the output to stdout.
800 args = ["a", "unused", "-tgzip", "-so", tarFile]; 800 args = ["a", "unused", "-tgzip", "-so", tarFile];
801 return startProcess(pathTo7zip, args); 801 return startProcess(pathTo7zip, args);
802 }).then((process) { 802 }).then((process) {
803 // Ignore 7zip's stderr. 7zip writes its normal output to stderr. We don't 803 // Ignore 7zip's stderr. 7zip writes its normal output to stderr. We don't
804 // want to show that since it's meaningless. 804 // want to show that since it's meaningless.
805 // 805 //
806 // TODO(rnystrom): Should log the stderr and display it if an actual error 806 // TODO(rnystrom): Should log the stderr and display it if an actual error
807 // occurs. 807 // occurs.
808 return store(process.stdout, controller); 808 return store(process.stdout, controller);
809 }); 809 });
810 }).catchError((e) { 810 }).catchError((e, stackTrace) {
811 // We don't have to worry about double-signaling here, since the store() 811 // We don't have to worry about double-signaling here, since the store()
812 // above will only be reached if everything succeeds. 812 // above will only be reached if everything succeeds.
813 controller.addError(e); 813 controller.addError(e, stackTrace);
814 controller.close(); 814 controller.close();
815 }); 815 });
816 return new ByteStream(controller.stream); 816 return new ByteStream(controller.stream);
817 } 817 }
818 818
819 /// Exception thrown when an operation times out. 819 /// Exception thrown when an operation times out.
820 class TimeoutException implements Exception { 820 class TimeoutException implements Exception {
821 final String message; 821 final String message;
822 822
823 const TimeoutException(this.message); 823 const TimeoutException(this.message);
(...skipping 10 matching lines...) Expand all
834 const PubProcessResult(this.stdout, this.stderr, this.exitCode); 834 const PubProcessResult(this.stdout, this.stderr, this.exitCode);
835 835
836 bool get success => exitCode == 0; 836 bool get success => exitCode == 0;
837 } 837 }
838 838
839 /// Gets a [Uri] for [uri], which can either already be one, or be a [String]. 839 /// Gets a [Uri] for [uri], which can either already be one, or be a [String].
840 Uri _getUri(uri) { 840 Uri _getUri(uri) {
841 if (uri is Uri) return uri; 841 if (uri is Uri) return uri;
842 return Uri.parse(uri); 842 return Uri.parse(uri);
843 } 843 }
OLDNEW
« no previous file with comments | « sdk/lib/_internal/pub/lib/src/barback/server.dart ('k') | sdk/lib/_internal/pub/lib/src/safe_http_server.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698