UNPKG

3.23 kBJavaScriptView Raw
1// Copyright © 2017, 2018 IBM Corp. All rights reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14'use strict';
15
16// fatal errors
17const codes = {
18 Error: 1,
19 InvalidOption: 2,
20 DatabaseNotFound: 10,
21 Unauthorized: 11,
22 Forbidden: 12,
23 NoLogFileName: 20,
24 LogDoesNotExist: 21,
25 IncompleteChangesInLogFile: 22,
26 SpoolChangesError: 30,
27 HTTPFatalError: 40,
28 BulkGetError: 50
29};
30
31class BackupError extends Error {
32 constructor(name, message) {
33 super(message);
34 this.name = name;
35 }
36}
37
38class HTTPError extends BackupError {
39 constructor(responseError, name) {
40 var errMsg = `${responseError.statusCode} ${responseError.statusMessage || ''}: ` +
41 `${responseError.request.method} ${(typeof responseError.request.uri === 'object') ? responseError.request.uri.href : responseError.request.uri}`;
42 if (responseError.error && responseError.reason) {
43 errMsg += ` - Error: ${responseError.error}, Reason: ${responseError.reason}`;
44 }
45 // Special case some names for more useful error messages
46 switch (responseError.statusCode) {
47 case 401:
48 name = 'Unauthorized';
49 break;
50 case 403:
51 name = 'Forbidden';
52 break;
53 default:
54 name = name || 'HTTPFatalError';
55 }
56 super(name, errMsg);
57 }
58}
59
60// Default function to return an error for HTTP status codes
61// < 400 -> OK
62// 4XX (except 429) -> Fatal
63// 429 & >=500 -> Transient
64function checkResponse(err) {
65 if (err) {
66 // Construct an HTTPError if there is request information on the error
67 // Codes < 400 are considered OK
68 if (err.statusCode >= 400) {
69 return new HTTPError(err);
70 } else {
71 // Send it back again if there was no status code, e.g. a cxn error
72 return augmentMessage(err);
73 }
74 }
75}
76
77function convertResponseError(responseError, errorFactory) {
78 if (!errorFactory) {
79 errorFactory = checkResponse;
80 }
81 return errorFactory(responseError);
82}
83
84function augmentMessage(err) {
85 // For errors that don't have a status code, we are likely looking at a cxn
86 // error.
87 // Try to augment the message with more detail
88 // TODO add this extra message detail to nano?
89 if (err && err.code) {
90 err.message = `${err.message} ${err.code}`;
91 }
92 if (err && err.description) {
93 err.message = `${err.message} ${err.description}`;
94 }
95 return err;
96}
97
98module.exports = {
99 BackupError: BackupError,
100 HTTPError: HTTPError,
101 convertResponseError: convertResponseError,
102 terminationCallback: function terminationCallback(err, data) {
103 if (err) {
104 process.on('uncaughtException', function(err) {
105 console.error(`ERROR: ${err.message}`);
106 process.exitCode = codes[err.name] || 1;
107 });
108 throw err;
109 }
110 }
111};