uapi-json 1.16.5 → 1.17.1
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/docs/Terminal.md +19 -0
- package/package.json +1 -1
- package/src/Services/Terminal/Terminal.js +54 -57
package/docs/Terminal.md
CHANGED
|
@@ -21,6 +21,25 @@ for several PCC emulations.
|
|
|
21
21
|
See [advanced emulation example](../examples/Terminal/emulation.js) to get an example
|
|
22
22
|
on how to use emulation.
|
|
23
23
|
|
|
24
|
+
# uAPI error handling
|
|
25
|
+
|
|
26
|
+
In case you want to handle some specific errors from uAPI, you can provde `uapiErrorHandler` function
|
|
27
|
+
in options.
|
|
28
|
+
|
|
29
|
+
Function should return response from retried command or any other command.
|
|
30
|
+
|
|
31
|
+
Footprint of the functions should be as follows:
|
|
32
|
+
```javascript
|
|
33
|
+
async (
|
|
34
|
+
executeCommandWithRetry,
|
|
35
|
+
{ command, error: err }
|
|
36
|
+
) => {
|
|
37
|
+
// your code goes here
|
|
38
|
+
// response is an array of strings (lines of terminal response)
|
|
39
|
+
return response;
|
|
40
|
+
}
|
|
41
|
+
```
|
|
42
|
+
|
|
24
43
|
# Session closing
|
|
25
44
|
Be aware to close the session after all your manipulations with the terminal.
|
|
26
45
|
|
package/package.json
CHANGED
|
@@ -16,6 +16,7 @@ const autoCloseTerminals = [];
|
|
|
16
16
|
const ERROR_INFO_SUFFIX = 'ErrorInfo';
|
|
17
17
|
const ERROR_CODE_SUFFIX = 'Code';
|
|
18
18
|
const RETRY_CODES_LIST = ['14058'];
|
|
19
|
+
const MD_COMMAND = 'MD';
|
|
19
20
|
|
|
20
21
|
const DEFAULT_RETRY_TIMES = 3;
|
|
21
22
|
|
|
@@ -100,69 +101,21 @@ const isErrorRetriable = (e) => {
|
|
|
100
101
|
return (errorCode && RETRY_CODES_LIST.includes(errorCode));
|
|
101
102
|
};
|
|
102
103
|
|
|
103
|
-
const commandRetry = async ({
|
|
104
|
-
service,
|
|
105
|
-
command,
|
|
106
|
-
sessionToken,
|
|
107
|
-
times = DEFAULT_RETRY_TIMES,
|
|
108
|
-
}) => {
|
|
109
|
-
try {
|
|
110
|
-
return await service.executeCommand({ command, sessionToken });
|
|
111
|
-
} catch (e) {
|
|
112
|
-
if (!isErrorRetriable(e) || times <= 0) {
|
|
113
|
-
throw e;
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
return commandRetry({
|
|
117
|
-
service,
|
|
118
|
-
command,
|
|
119
|
-
sessionToken,
|
|
120
|
-
times: times - 1,
|
|
121
|
-
});
|
|
122
|
-
}
|
|
123
|
-
};
|
|
124
|
-
|
|
125
104
|
module.exports = function (settings) {
|
|
126
|
-
const
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
const autoClose = settings.autoClose === undefined
|
|
132
|
-
? true
|
|
133
|
-
: settings.autoClose;
|
|
105
|
+
const {
|
|
106
|
+
timeout = false, debug = 0, autoClose = true,
|
|
107
|
+
auth: { emulatePcc = false, token = null } = {},
|
|
108
|
+
options: { logFunction: log = console.log, uapiErrorHandler = null } = {},
|
|
109
|
+
} = settings;
|
|
134
110
|
|
|
111
|
+
const service = terminalService(validateServiceSettings(settings));
|
|
135
112
|
const defaultStopMD = (screens) => !screenFunctions.hasMore(screens);
|
|
136
|
-
const token = settings.auth.token || null;
|
|
137
113
|
|
|
138
114
|
const state = {
|
|
139
115
|
terminalState: TERMINAL_STATE_NONE,
|
|
140
116
|
sessionToken: token,
|
|
141
117
|
};
|
|
142
118
|
|
|
143
|
-
// Processing response with MD commands
|
|
144
|
-
const processResponse = (response, stopMD, previousResponse = null) => {
|
|
145
|
-
const processedResponse = previousResponse
|
|
146
|
-
? screenFunctions.mergeResponse(
|
|
147
|
-
previousResponse,
|
|
148
|
-
response.join('\n')
|
|
149
|
-
)
|
|
150
|
-
: response.join('\n');
|
|
151
|
-
if (stopMD(processedResponse)) {
|
|
152
|
-
return processedResponse;
|
|
153
|
-
}
|
|
154
|
-
return commandRetry({
|
|
155
|
-
service,
|
|
156
|
-
sessionToken: state.sessionToken,
|
|
157
|
-
command: 'MD',
|
|
158
|
-
}).then(
|
|
159
|
-
(mdResponse) => (
|
|
160
|
-
mdResponse.join('\n') === response.join('\n')
|
|
161
|
-
? processedResponse
|
|
162
|
-
: processResponse(mdResponse, stopMD, processedResponse)
|
|
163
|
-
)
|
|
164
|
-
);
|
|
165
|
-
};
|
|
166
119
|
// Getting session token
|
|
167
120
|
const getSessionToken = () => new Promise((resolve, reject) => {
|
|
168
121
|
if (state.terminalState === TERMINAL_STATE_BUSY) {
|
|
@@ -208,22 +161,66 @@ module.exports = function (settings) {
|
|
|
208
161
|
.then(resolve)
|
|
209
162
|
.catch(reject);
|
|
210
163
|
});
|
|
164
|
+
|
|
165
|
+
// Runtime error handling
|
|
166
|
+
const executeCommandWithRetry = async (command, times = DEFAULT_RETRY_TIMES) => {
|
|
167
|
+
const { sessionToken } = state;
|
|
168
|
+
try {
|
|
169
|
+
return await service.executeCommand({ command, sessionToken });
|
|
170
|
+
} catch (e) {
|
|
171
|
+
if (!isErrorRetriable(e) || times <= 0) {
|
|
172
|
+
if (uapiErrorHandler) {
|
|
173
|
+
return uapiErrorHandler(
|
|
174
|
+
executeCommandWithRetry,
|
|
175
|
+
{ command, error: e }
|
|
176
|
+
);
|
|
177
|
+
}
|
|
178
|
+
throw e;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
return executeCommandWithRetry(command, times - 1);
|
|
182
|
+
}
|
|
183
|
+
};
|
|
184
|
+
|
|
185
|
+
// Processing response with MD commands
|
|
186
|
+
const processResponse = (response, stopMD, previousResponse = null) => {
|
|
187
|
+
const processedResponse = previousResponse
|
|
188
|
+
? screenFunctions.mergeResponse(
|
|
189
|
+
previousResponse,
|
|
190
|
+
response.join('\n')
|
|
191
|
+
)
|
|
192
|
+
: response.join('\n');
|
|
193
|
+
|
|
194
|
+
// Full response is processed no MD commands needed
|
|
195
|
+
if (stopMD(processedResponse)) {
|
|
196
|
+
return processedResponse;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
// Processing MD commands
|
|
200
|
+
return executeCommandWithRetry(MD_COMMAND).then(
|
|
201
|
+
(mdResponse) => (
|
|
202
|
+
mdResponse.join('\n') === response.join('\n')
|
|
203
|
+
? processedResponse
|
|
204
|
+
: processResponse(mdResponse, stopMD, processedResponse)
|
|
205
|
+
)
|
|
206
|
+
);
|
|
207
|
+
};
|
|
208
|
+
|
|
211
209
|
// Get terminal ID
|
|
212
210
|
const getTerminalId = (sessionToken) => getHashSubstr(sessionToken);
|
|
213
211
|
|
|
214
212
|
const terminal = {
|
|
215
213
|
getToken: getSessionToken,
|
|
216
|
-
executeCommand: async (
|
|
214
|
+
executeCommand: async (command, stopMD = defaultStopMD) => {
|
|
217
215
|
try {
|
|
218
216
|
const sessionToken = await getSessionToken();
|
|
219
217
|
const terminalId = getTerminalId(sessionToken);
|
|
220
|
-
const command = rawCommand.replace(/;/g, '\t');
|
|
221
218
|
|
|
222
219
|
if (debug) {
|
|
223
220
|
log(`[${terminalId}] Terminal request:\n${command}`);
|
|
224
221
|
}
|
|
225
222
|
|
|
226
|
-
const screen = await
|
|
223
|
+
const screen = await executeCommandWithRetry(command);
|
|
227
224
|
const response = await processResponse(screen, stopMD);
|
|
228
225
|
|
|
229
226
|
if (debug) {
|