Browse Source

Move marker and error handling so that it doesn't occur for every single successful value

Sven Slootweg 3 months ago
parent
commit
2976a37e0e
1 changed files with 51 additions and 49 deletions
  1. 51 49
      index.js

+ 51 - 49
index.js

@ -3,8 +3,8 @@
3 3
const Promise = require("bluebird");
4 4
const propagateAbort = require("@ppstreams/propagate-abort");
5 5
const propagatePeek = require("@ppstreams/propagate-peek");
6
const { isEndOfStream } = require("@ppstreams/end-of-stream-marker");
7
const { isAborted } = require("@ppstreams/aborted-marker");
6
const isEndOfStream = require("@ppstreams/is-end-of-stream");
7
const isAborted = require("@ppstreams/is-aborted");
8 8
9 9
const { validateOptions } = require("@validatem/core");
10 10
const required = require("@validatem/required");
@ -48,58 +48,60 @@ module.exports = function simpleSinkStream(_options) {
48 48
					lastResult = result;
49 49
50 50
					return attemptRead();
51
				}).catch(isEndOfStream, () => {
52
					/* Don't attempt to do another read, we're done.  */
53
					if (onEndCalled) {
54
						return onEndResult;
55
					} else {
56
						return Promise.try(() => {
57
							return onEnd();
58
						}).then((result) => {
59
							onEndResult = result;
60
							return result;
61
						});
62
					}
63
				}).catch((error) => !isAborted(error), (error) => {
64
					return Promise.try(() => {
65
						return source.abort(error);
66
					}).catch((abortError) => {
67
						let message = [
68
							`Tried to abort stream due to encountering an error, but the aborting itself failed`,
69
							`Original error message: ${error.message}`,
70
							`Abort failure message: ${abortError.message}`
71
						].join("\n");
51
				});
52
			}
72 53
73
						// FIXME: Make this some sort of chained error
74
						let combinedError = new Error(message);
75
						combinedError.stack = abortError.stack; // HACK
76
						throw combinedError;
77
					}).then(() => {
78
						// Pass through the original error to the user
79
						throw error;
54
			return Promise.try(() => {
55
				return attemptRead();
56
			}).catch(isEndOfStream, () => {
57
				/* Don't attempt to do another read, we're done.  */
58
				if (onEndCalled) {
59
					return onEndResult;
60
				} else {
61
					return Promise.try(() => {
62
						return onEnd();
63
					}).then((result) => {
64
						onEndResult = result;
65
						return result;
80 66
					});
81
				}).catch(isAborted, (marker) => {
82
					if (abortHandled === false) {
83
						abortHandled = true;
67
				}
68
			}).catch((error) => !isAborted(error), (error) => {
69
				return Promise.try(() => {
70
					return source.abort(error);
71
				}).catch((abortError) => {
72
					let message = [
73
						`Tried to abort stream due to encountering an error, but the aborting itself failed`,
74
						`Original error message: ${error.message}`,
75
						`Abort failure message: ${abortError.message}`
76
					].join("\n");
84 77
85
						return Promise.try(() => {
86
							return onAbort();
87
						}).then(() => {
88
							if (marker.reason instanceof Error) {
89
								// NOTE: This ensures that the original error causing the abort is thrown exactly once
90
								throw marker.reason;
91
							} else {
92
								throw marker;
93
							}
94
						});
95
					} else {
96
						// Don't interfere, we only need special behaviour on the first occurrence
97
						throw marker;
98
					}
78
					// FIXME: Make this some sort of chained error
79
					let combinedError = new Error(message);
80
					combinedError.stack = abortError.stack; // HACK
81
					throw combinedError;
82
				}).then(() => {
83
					// Pass through the original error to the user
84
					throw error;
99 85
				});
100
			}
86
			}).catch(isAborted, (marker) => {
87
				if (abortHandled === false) {
88
					abortHandled = true;
101 89
102
			return attemptRead();
90
					return Promise.try(() => {
91
						return onAbort();
92
					}).then(() => {
93
						if (marker.reason instanceof Error) {
94
							// NOTE: This ensures that the original error causing the abort is thrown exactly once
95
							throw marker.reason;
96
						} else {
97
							throw marker;
98
						}
99
					});
100
				} else {
101
					// Don't interfere, we only need special behaviour on the first occurrence
102
					throw marker;
103
				}
104
			});
103 105
		}
104 106
	};
105 107
};