OLD | NEW |
---|---|
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 'use strict'; | 5 'use strict'; |
6 | 6 |
7 /** @suppress {duplicate} */ | 7 /** @suppress {duplicate} */ |
8 var remoting = remoting || {}; | 8 var remoting = remoting || {}; |
9 | 9 |
10 /** | 10 /** |
11 * A wrapper for remoting.Error.Tag. Having a wrapper makes it | |
12 * possible to use instanceof checks on caught exceptions. It also | |
13 * allows adding more detailed error information if desired. | |
14 * | |
15 * @constructor | |
16 * @param {remoting.Error.Tag} tag | |
17 * @param {string=} opt_message | |
18 */ | |
19 remoting.Error = function(tag, opt_message) { | |
20 /** @const */ | |
21 this.tag = tag; | |
22 | |
23 /** @const {?string} */ | |
24 this.message = opt_message || null; | |
25 }; | |
26 | |
27 /** | |
28 * @return {boolean} True if this object represents an error | |
29 * condition. | |
30 */ | |
31 remoting.Error.prototype.isError = function() { | |
32 return this.tag != remoting.Error.Tag.NONE; | |
33 }; | |
34 | |
35 /** | |
11 * @enum {string} All error messages from messages.json | 36 * @enum {string} All error messages from messages.json |
12 */ | 37 */ |
13 remoting.Error = { | 38 remoting.Error.Tag = { |
14 NONE: '', | 39 NONE: '', |
15 | 40 |
16 // Used to signify that an operation was cancelled by the user. This should | 41 // Used to signify that an operation was cancelled by the user. This should |
17 // not normally cause the error text to be shown to the user, so the | 42 // not normally cause the error text to be shown to the user, so the |
18 // i18n-content prefix is not needed in this case. | 43 // i18n-content prefix is not needed in this case. |
19 CANCELLED: '__CANCELLED__', | 44 CANCELLED: '__CANCELLED__', |
20 | 45 |
21 INVALID_ACCESS_CODE: /*i18n-content*/'ERROR_INVALID_ACCESS_CODE', | 46 INVALID_ACCESS_CODE: /*i18n-content*/'ERROR_INVALID_ACCESS_CODE', |
22 MISSING_PLUGIN: /*i18n-content*/'ERROR_MISSING_PLUGIN', | 47 MISSING_PLUGIN: /*i18n-content*/'ERROR_MISSING_PLUGIN', |
23 AUTHENTICATION_FAILED: /*i18n-content*/'ERROR_AUTHENTICATION_FAILED', | 48 AUTHENTICATION_FAILED: /*i18n-content*/'ERROR_AUTHENTICATION_FAILED', |
24 HOST_IS_OFFLINE: /*i18n-content*/'ERROR_HOST_IS_OFFLINE', | 49 HOST_IS_OFFLINE: /*i18n-content*/'ERROR_HOST_IS_OFFLINE', |
25 INCOMPATIBLE_PROTOCOL: /*i18n-content*/'ERROR_INCOMPATIBLE_PROTOCOL', | 50 INCOMPATIBLE_PROTOCOL: /*i18n-content*/'ERROR_INCOMPATIBLE_PROTOCOL', |
26 BAD_PLUGIN_VERSION: /*i18n-content*/'ERROR_BAD_PLUGIN_VERSION', | 51 BAD_PLUGIN_VERSION: /*i18n-content*/'ERROR_BAD_PLUGIN_VERSION', |
27 NETWORK_FAILURE: /*i18n-content*/'ERROR_NETWORK_FAILURE', | 52 NETWORK_FAILURE: /*i18n-content*/'ERROR_NETWORK_FAILURE', |
28 HOST_OVERLOAD: /*i18n-content*/'ERROR_HOST_OVERLOAD', | 53 HOST_OVERLOAD: /*i18n-content*/'ERROR_HOST_OVERLOAD', |
29 UNEXPECTED: /*i18n-content*/'ERROR_UNEXPECTED', | 54 UNEXPECTED: /*i18n-content*/'ERROR_UNEXPECTED', |
30 SERVICE_UNAVAILABLE: /*i18n-content*/'ERROR_SERVICE_UNAVAILABLE', | 55 SERVICE_UNAVAILABLE: /*i18n-content*/'ERROR_SERVICE_UNAVAILABLE', |
31 NOT_AUTHENTICATED: /*i18n-content*/'ERROR_NOT_AUTHENTICATED', | 56 NOT_AUTHENTICATED: /*i18n-content*/'ERROR_NOT_AUTHENTICATED', |
32 INVALID_HOST_DOMAIN: /*i18n-content*/'ERROR_INVALID_HOST_DOMAIN', | 57 INVALID_HOST_DOMAIN: /*i18n-content*/'ERROR_INVALID_HOST_DOMAIN', |
33 P2P_FAILURE: /*i18n-content*/'ERROR_P2P_FAILURE', | 58 P2P_FAILURE: /*i18n-content*/'ERROR_P2P_FAILURE', |
34 REGISTRATION_FAILED: /*i18n-content*/'ERROR_HOST_REGISTRATION_FAILED', | 59 REGISTRATION_FAILED: /*i18n-content*/'ERROR_HOST_REGISTRATION_FAILED', |
35 NOT_AUTHORIZED: /*i18n-content*/'ERROR_NOT_AUTHORIZED', | 60 NOT_AUTHORIZED: /*i18n-content*/'ERROR_NOT_AUTHORIZED', |
36 | 61 |
37 // TODO(garykac): Move app-specific errors into separate location. | 62 // TODO(garykac): Move app-specific errors into separate location. |
38 APP_NOT_AUTHORIZED: /*i18n-content*/'ERROR_APP_NOT_AUTHORIZED' | 63 APP_NOT_AUTHORIZED: /*i18n-content*/'ERROR_APP_NOT_AUTHORIZED' |
39 }; | 64 }; |
40 | 65 |
66 // A whole bunch of semi-redundant constants, mostly to reduce to size | |
67 // of the diff that introduced the remoting.Error class. | |
68 // | |
69 // Please don't add any more constants here; just call the | |
70 // remoting.Error constructor directly | |
Jamie
2015/03/09 23:53:45
Apologies for adding a comment so late, but it occ
| |
71 | |
72 /** @const */ | |
73 remoting.Error.NONE = new remoting.Error(remoting.Error.Tag.NONE); | |
74 | |
75 /** @const */ | |
76 remoting.Error.CANCELLED = | |
77 new remoting.Error(remoting.Error.Tag.CANCELLED); | |
78 | |
79 /** @const */ | |
80 remoting.Error.INVALID_ACCESS_CODE = | |
81 new remoting.Error(remoting.Error.Tag.INVALID_ACCESS_CODE); | |
82 | |
83 /** @const */ | |
84 remoting.Error.MISSING_PLUGIN = | |
85 new remoting.Error(remoting.Error.Tag.MISSING_PLUGIN); | |
86 | |
87 /** @const */ | |
88 remoting.Error.AUTHENTICATION_FAILED = | |
89 new remoting.Error(remoting.Error.Tag.AUTHENTICATION_FAILED); | |
90 | |
91 /** @const */ | |
92 remoting.Error.HOST_IS_OFFLINE = | |
93 new remoting.Error(remoting.Error.Tag.HOST_IS_OFFLINE); | |
94 | |
95 /** @const */ | |
96 remoting.Error.INCOMPATIBLE_PROTOCOL = | |
97 new remoting.Error(remoting.Error.Tag.INCOMPATIBLE_PROTOCOL); | |
98 | |
99 /** @const */ | |
100 remoting.Error.BAD_PLUGIN_VERSION = | |
101 new remoting.Error(remoting.Error.Tag.BAD_PLUGIN_VERSION); | |
102 | |
103 /** @const */ | |
104 remoting.Error.NETWORK_FAILURE = | |
105 new remoting.Error(remoting.Error.Tag.NETWORK_FAILURE); | |
106 | |
107 /** @const */ | |
108 remoting.Error.HOST_OVERLOAD = | |
109 new remoting.Error(remoting.Error.Tag.HOST_OVERLOAD); | |
110 | |
111 /** @const */ | |
112 remoting.Error.UNEXPECTED = | |
113 new remoting.Error(remoting.Error.Tag.UNEXPECTED); | |
114 | |
115 /** @const */ | |
116 remoting.Error.SERVICE_UNAVAILABLE = | |
117 new remoting.Error(remoting.Error.Tag.SERVICE_UNAVAILABLE); | |
118 | |
119 /** @const */ | |
120 remoting.Error.NOT_AUTHENTICATED = | |
121 new remoting.Error(remoting.Error.Tag.NOT_AUTHENTICATED); | |
122 | |
123 /** @const */ | |
124 remoting.Error.INVALID_HOST_DOMAIN = | |
125 new remoting.Error(remoting.Error.Tag.INVALID_HOST_DOMAIN); | |
126 | |
127 /** @const */ | |
128 remoting.Error.P2P_FAILURE = | |
129 new remoting.Error(remoting.Error.Tag.P2P_FAILURE); | |
130 | |
131 /** @const */ | |
132 remoting.Error.REGISTRATION_FAILED = | |
133 new remoting.Error(remoting.Error.Tag.REGISTRATION_FAILED); | |
134 | |
135 /** @const */ | |
136 remoting.Error.NOT_AUTHORIZED = | |
137 new remoting.Error(remoting.Error.Tag.NOT_AUTHORIZED); | |
138 | |
139 /** @const */ | |
140 remoting.Error.APP_NOT_AUTHORIZED = | |
141 new remoting.Error(remoting.Error.Tag.APP_NOT_AUTHORIZED); | |
142 | |
41 /** | 143 /** |
42 * @param {number} httpStatus An HTTP status code. | 144 * @param {number} httpStatus An HTTP status code. |
43 * @return {remoting.Error} The remoting.Error enum corresponding to the | 145 * @return {!remoting.Error} The remoting.Error enum corresponding to the |
44 * specified HTTP status code. | 146 * specified HTTP status code. |
45 */ | 147 */ |
46 remoting.Error.fromHttpStatus = function(httpStatus) { | 148 remoting.Error.fromHttpStatus = function(httpStatus) { |
47 if (httpStatus == 0) { | 149 if (httpStatus == 0) { |
48 return remoting.Error.NETWORK_FAILURE; | 150 return remoting.Error.NETWORK_FAILURE; |
49 } else if (httpStatus >= 200 && httpStatus < 300) { | 151 } else if (httpStatus >= 200 && httpStatus < 300) { |
50 return remoting.Error.NONE; | 152 return remoting.Error.NONE; |
51 } else if (httpStatus == 400 || httpStatus == 401) { | 153 } else if (httpStatus == 400 || httpStatus == 401) { |
52 return remoting.Error.AUTHENTICATION_FAILED; | 154 return remoting.Error.AUTHENTICATION_FAILED; |
53 } else if (httpStatus >= 500 && httpStatus < 600) { | 155 } else if (httpStatus >= 500 && httpStatus < 600) { |
54 return remoting.Error.SERVICE_UNAVAILABLE; | 156 return remoting.Error.SERVICE_UNAVAILABLE; |
55 } else { | 157 } else { |
56 console.warn('Unexpected HTTP error code: ' + httpStatus); | 158 console.warn('Unexpected HTTP error code: ' + httpStatus); |
159 | |
57 // Return AUTHENTICATION_FAILED by default, so that the user can try to | 160 // Return AUTHENTICATION_FAILED by default, so that the user can try to |
58 // recover from an unexpected failure by signing in again. | 161 // recover from an unexpected failure by signing in again. |
59 // TODO(jamiewalch): Return UNEXPECTED here and let calling code treat that | 162 // TODO(jamiewalch): Tag = UNEXPECTED here and let calling tag treat that |
60 // as "sign-in required" if necessary. | 163 // as "sign-in required" if necessary. |
61 return remoting.Error.AUTHENTICATION_FAILED; | 164 return remoting.Error.AUTHENTICATION_FAILED; |
62 } | 165 } |
63 }; | 166 }; |
64 | 167 |
65 /** | 168 /** |
66 * Create an error-handling function suitable for passing to a | 169 * Create an error-handling function suitable for passing to a |
67 * Promise's "catch" method. | 170 * Promise's "catch" method. |
68 * | 171 * |
69 * @param {function(remoting.Error):void} onError | 172 * @param {function(!remoting.Error):void} onError |
70 * @return {function(*):void} | 173 * @return {function(*):void} |
71 */ | 174 */ |
72 remoting.Error.handler = function(onError) { | 175 remoting.Error.handler = function(onError) { |
73 return function(/** * */ error) { | 176 return function(/** * */ error) { |
74 if (typeof error == 'string') { | 177 if (error instanceof remoting.Error) { |
75 onError(/** @type {remoting.Error} */ (error)); | 178 onError(/** @type {!remoting.Error} */ (error)); |
76 } else { | 179 } else { |
77 console.error('Unexpected error: %o', error); | 180 console.error('Unexpected error: %o', error); |
78 onError(remoting.Error.UNEXPECTED); | 181 onError(remoting.Error.UNEXPECTED); |
79 } | 182 } |
80 }; | 183 }; |
81 }; | 184 }; |
82 | |
83 // /** | |
84 // * @param {(!Promise<T>| | |
85 // * function(function(T):void,function(remoting.Error):void))} arg | |
86 // * @constructor | |
87 // * @template T | |
88 // */ | |
89 // remoting.Promise = function(arg) { | |
90 // var promise; | |
91 // if (typeof arg == 'function') { | |
92 // promise = new Promise(arg); | |
93 // } else { | |
94 // promise = arg; | |
95 // } | |
96 | |
97 // /** @const */ | |
98 // this.promise = promise; | |
99 // }; | |
100 | |
101 // /** | |
102 // * @param {?function(T)} onResolve | |
103 // * @param {?function(remoting.Error)=} opt_onReject | |
104 // * @return {!remoting.Promise} | |
105 // */ | |
106 // remoting.Promise.prototype.then = function(onResolve, opt_onReject) { | |
107 // return new remoting.Promise(this.promise.then( | |
108 // onResolve, | |
109 // opt_onReject && function(/** * */ error) { | |
110 // if (typeof error == 'string') { | |
111 // opt_onReject(/** @type {remoting.Error} */ (error)); | |
112 // } else { | |
113 // console.error('Unexpected error: %o', error); | |
114 // opt_onReject(remoting.Error.UNEXPECTED); | |
115 // } | |
116 // })); | |
117 // }; | |
118 | |
119 // /** | |
120 // * @param {?function(remoting.Error)} onReject | |
121 // * @return {!remoting.Promise<T>} | |
122 // */ | |
123 // remoting.Promise.prototype.catch = function(onReject) { | |
124 // return this.then(null, onReject); | |
125 // }; | |
OLD | NEW |