ssh2-sftp-client 8.1.0 → 9.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/utils.js CHANGED
@@ -1,63 +1,7 @@
1
- 'use strict';
2
-
3
1
  const fs = require('fs');
4
2
  const path = require('path');
5
-
6
3
  const { errorCode } = require('./constants');
7
4
 
8
- /**
9
- * Generate a new Error object with a reformatted error message which
10
- * is a little more informative and useful to users.
11
- *
12
- * @param {Error|string} err - The Error object the new error will be based on
13
- * @param {number} retryCount - For those functions which use retry. Number of
14
- * attempts to complete before giving up
15
- * @returns {Error} New error with custom error message
16
- */
17
- function fmtError(err, name = 'sftp', eCode, retryCount) {
18
- let msg = '';
19
- let code = '';
20
- let retry = retryCount
21
- ? ` after ${retryCount} ${retryCount > 1 ? 'attempts' : 'attempt'}`
22
- : '';
23
-
24
- if (err === undefined) {
25
- msg = `${name}: Undefined error - probably a bug!`;
26
- code = errorCode.generic;
27
- } else if (typeof err === 'string') {
28
- msg = `${name}: ${err}${retry}`;
29
- code = eCode ? eCode : errorCode.generic;
30
- } else if (err.custom) {
31
- msg = `${name}->${err.message}${retry}`;
32
- code = err.code;
33
- } else {
34
- switch (err.code) {
35
- case 'ENOTFOUND':
36
- msg =
37
- `${name}: ${err.level} error. ` +
38
- `Address lookup failed for host ${err.hostname}${retry}`;
39
- break;
40
- case 'ECONNREFUSED':
41
- msg =
42
- `${name}: ${err.level} error. Remote host at ` +
43
- `${err.address} refused connection${retry}`;
44
- break;
45
- case 'ECONNRESET':
46
- msg =
47
- `${name}: Remote host has reset the connection: ` +
48
- `${err.message}${retry}`;
49
- break;
50
- default:
51
- msg = `${name}: ${err.message}${retry}`;
52
- }
53
- code = err.code ? err.code : errorCode.generic;
54
- }
55
- let newError = new Error(msg);
56
- newError.code = code;
57
- newError.custom = true;
58
- return newError;
59
- }
60
-
61
5
  /**
62
6
  * Simple default error listener. Will reformat the error message and
63
7
  * throw a new error.
@@ -66,82 +10,94 @@ function fmtError(err, name = 'sftp', eCode, retryCount) {
66
10
  * @throws {Error} Throws new error
67
11
  */
68
12
  function errorListener(client, name, reject) {
69
- let fn = (err) => {
13
+ const fn = (err) => {
70
14
  if (client.endCalled || client.errorHandled) {
71
- client.debugMsg(`${name} Error: Ignoring handled error: ${err.message}`);
15
+ // error already handled or expected - ignore
16
+ client.debugMsg(`${name} errorListener - ignoring handled error`);
17
+ return;
18
+ }
19
+ client.errorHandled = true;
20
+ const newError = new Error(`${name}: ${err.message}`);
21
+ newError.code = err.code;
22
+ if (reject) {
23
+ reject(newError);
72
24
  } else {
73
- client.debugMsg(`${name} Error: Handling error: ${err.message}`);
74
- client.errorHandled = true;
75
- if (reject) {
76
- client.debugMsg(`${name} Error: handled error with reject`);
77
- reject(fmtError(err, name, err.code));
78
- } else {
79
- client.debugMsg(`${name} Error: handling error with throw`);
80
- throw fmtError(err, name, err.code);
81
- }
25
+ throw newError;
82
26
  }
83
27
  };
84
28
  return fn;
85
29
  }
86
30
 
87
31
  function endListener(client, name, reject) {
88
- let fn = function () {
89
- if (client.endCalled || client.endHandled) {
90
- client.debugMsg(`${name} End: Ignoring expected end event`);
91
- } else {
92
- client.debugMsg(`${name} End: Handling end event`);
93
- client.sftp = undefined;
94
- client.endHandled = true;
95
- if (reject) {
96
- client.debugMsg(`${name} End: handling end event with reject'`);
97
- reject(fmtError('Unexpected end event raised', name));
98
- } else {
99
- client.debugMsg(`${name} End: handling end event with throw`);
100
- throw fmtError('Unexpected end event raised', name);
101
- }
32
+ const fn = function () {
33
+ client.sftp = undefined;
34
+ if (client.endCalled || client.endHandled || client.errorHandled) {
35
+ // end event already handled - ignore
36
+ client.debugMsg(`${name} endListener - ignoring handled error`);
37
+ return;
102
38
  }
39
+ client.endHandled = true;
40
+ client.debugMsg(`${name} Unexpected end event - ignoring`);
41
+ // Don't reject/throw error, just log it and move on
42
+ // after invalidating the connection
43
+ // const err = new Error(`${name} Unexpected end event raised`);
44
+ // if (reject) {
45
+ // reject(err);
46
+ // } else {
47
+ // throw err;
48
+ // }
103
49
  };
104
50
  return fn;
105
51
  }
106
52
 
107
53
  function closeListener(client, name, reject) {
108
- let fn = function () {
109
- if (client.endCalled || client.closeHandled) {
110
- client.debugMsg(`${name} Close: ignoring expected close event`);
111
- } else {
112
- client.debugMsg(`${name} Close: handling unexpected close event`);
113
- client.sftp = undefined;
114
- client.closeHandled = true;
115
- if (reject) {
116
- client.debugMsg(`${name} Close: handling close event with reject`);
117
- reject(fmtError('Unexpected close event raised', name));
118
- } else {
119
- client.debugMsg(`${name} Close: handling close event with throw`);
120
- throw fmtError('Unexpected close event raised', name);
121
- }
54
+ const fn = function () {
55
+ client.sftp = undefined;
56
+ if (
57
+ client.endCalled ||
58
+ client.closeHandled ||
59
+ client.errorHandled ||
60
+ client.endHandled
61
+ ) {
62
+ // handled or expected close event - ignore
63
+ client.debugMsg(`${name} closeListener - ignoring handled error`);
64
+ return;
122
65
  }
66
+ client.closeHandled = true;
67
+ client.debugMsg(`${name} Unexpected close event raised - ignoring`);
68
+ // Don't throw/reject on close events. Just invalidate the connection
69
+ // and move on.
70
+ // const err = new Error(`${name}: Unexpected close event raised`);
71
+ // if (reject) {
72
+ // reject(err);
73
+ // } else {
74
+ // throw err;
75
+ // }
123
76
  };
124
77
  return fn;
125
78
  }
126
79
 
127
80
  function addTempListeners(client, name, reject) {
128
- let listeners = {
81
+ const listeners = {
129
82
  end: endListener(client, name, reject),
130
83
  close: closeListener(client, name, reject),
131
84
  error: errorListener(client, name, reject),
132
85
  };
133
- client.debugMsg(`${name}: Adding temp event listeners`);
134
86
  client.on('end', listeners.end);
135
87
  client.on('close', listeners.close);
136
88
  client.on('error', listeners.error);
89
+ client._resetEventFlags();
137
90
  return listeners;
138
91
  }
139
92
 
140
93
  function removeTempListeners(client, listeners, name) {
141
- client.debugMsg(`${name}: Removing temp event listeners`);
142
- client.removeListener('end', listeners.end);
143
- client.removeListener('close', listeners.close);
144
- client.removeListener('error', listeners.error);
94
+ try {
95
+ client.removeListener('end', listeners.end);
96
+ client.removeListener('close', listeners.close);
97
+ client.removeListener('error', listeners.error);
98
+ } catch (err) {
99
+ throw new Error(`${name}: Error removing temp listeners: ${err.message}`);
100
+ }
145
101
  }
146
102
 
147
103
  /**
@@ -165,11 +121,9 @@ function localExists(filePath) {
165
121
  } else if (stats.isFile()) {
166
122
  return '-';
167
123
  } else {
168
- throw fmtError(
169
- `Bad path: ${filePath}: target must be a file or directory`,
170
- 'localExists',
171
- errorCode.badPath
172
- );
124
+ const err = new Error(`Bad path: ${filePath}: target must be a file or directory`);
125
+ err.code = errorCode.badPath;
126
+ throw err;
173
127
  }
174
128
  }
175
129
 
@@ -284,15 +238,15 @@ function haveLocalCreate(filePath) {
284
238
  async function normalizeRemotePath(client, aPath) {
285
239
  try {
286
240
  if (aPath.startsWith('..')) {
287
- let root = await client.realPath('..');
241
+ const root = await client.realPath('..');
288
242
  return root + client.remotePathSep + aPath.slice(3);
289
243
  } else if (aPath.startsWith('.')) {
290
- let root = await client.realPath('.');
244
+ const root = await client.realPath('.');
291
245
  return root + client.remotePathSep + aPath.slice(2);
292
246
  }
293
247
  return aPath;
294
248
  } catch (err) {
295
- throw fmtError(err, 'normalizeRemotePath');
249
+ throw new Error(`normalizeRemotePath: ${err.message}`);
296
250
  }
297
251
  }
298
252
 
@@ -308,11 +262,8 @@ async function normalizeRemotePath(client, aPath) {
308
262
  */
309
263
  function haveConnection(client, name, reject) {
310
264
  if (!client.sftp) {
311
- let newError = fmtError(
312
- 'No SFTP connection available',
313
- name,
314
- errorCode.connect
315
- );
265
+ const newError = new Error(`${name}: No SFTP connection available`);
266
+ newError.code = errorCode.connect;
316
267
  if (reject) {
317
268
  reject(newError);
318
269
  return false;
@@ -336,7 +287,6 @@ function sleep(ms) {
336
287
  }
337
288
 
338
289
  module.exports = {
339
- fmtError,
340
290
  errorListener,
341
291
  endListener,
342
292
  closeListener,