/
errors.ts
222 lines (205 loc) · 7.28 KB
/
errors.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import { logErrorStackTrace, logger } from "../log";
import Long from "long";
import { ConnectionContext } from "../connectionContext";
import { AmqpError } from "rhea-promise";
/**
* Error message to use when EntityPath in connection string does not match the
* queue or topic name passed to the methods in the ServiceBusClient that create
* senders and receivers.
*
* @internal
* @ignore
*/
export const entityPathMisMatchError =
"The queue or topic name provided does not match the EntityPath in the connection string passed to the ServiceBusClient constructor.";
/**
* @internal
* @ignore
* Logs and throws Error if the current AMQP connection is closed.
* @param context The ConnectionContext associated with the current AMQP connection.
*/
export function throwErrorIfConnectionClosed(context: ConnectionContext): void {
if (context && context.wasConnectionCloseCalled) {
const errorMessage = "The underlying AMQP connection is closed.";
const error = new Error(errorMessage);
logger.warning(`[${context.connectionId}] %O`, error);
throw error;
}
}
/**
* @internal
* @ignore
* Gets the error message when a sender is used when its already closed
* @param entityPath Value of the `entityPath` property on the client which denotes its name
*/
export function getSenderClosedErrorMsg(entityPath: string): string {
return (
`The sender for "${entityPath}" has been closed and can no longer be used. ` +
`Please create a new sender using the "createSender" method on the ServiceBusClient.`
);
}
/**
* @internal
* @ignore
* Gets the error message when a receiver is used when its already closed
* @param entityPath Value of the `entityPath` property on the client which denotes its name
* @param sessionId If using session receiver, then the id of the session
*/
export function getReceiverClosedErrorMsg(entityPath: string, sessionId?: string): string {
if (sessionId == undefined) {
return (
`The receiver for "${entityPath}" has been closed and can no longer be used. ` +
`Please create a new receiver using the "createReceiver" method on the ServiceBusClient.`
);
}
return (
`The receiver for session "${sessionId}" in "${entityPath}" has been closed and can no ` +
`longer be used. Please create a new receiver using the "createSessionReceiver" method on the ServiceBusClient.`
);
}
/**
* @internal
* @ignore
* @param entityPath Value of the `entityPath` property on the client which denotes its name
* @param sessionId If using session receiver, then the id of the session
*/
export function getAlreadyReceivingErrorMsg(entityPath: string, sessionId?: string): string {
if (sessionId == undefined) {
return `The receiver for "${entityPath}" is already receiving messages.`;
}
return `The receiver for session "${sessionId}" for "${entityPath}" is already receiving messages.`;
}
/**
* @internal
* @ignore
* Logs and Throws TypeError if given parameter is undefined or null
* @param connectionId Id of the underlying AMQP connection used for logging
* @param parameterName Name of the parameter to check
* @param parameterValue Value of the parameter to check
*/
export function throwTypeErrorIfParameterMissing(
connectionId: string,
parameterName: string,
parameterValue: any
): void {
if (parameterValue === undefined || parameterValue === null) {
const error = new TypeError(`Missing parameter "${parameterName}"`);
logger.warning(`[${connectionId}] %O`, error);
throw error;
}
}
/**
* @internal
* @ignore
* Logs and Throws TypeError if given parameter is not of expected type
* @param connectionId Id of the underlying AMQP connection used for logging
* @param parameterName Name of the parameter to type check
* @param parameterValue Value of the parameter to type check
* @param expectedType Expected type of the parameter
*/
export function throwTypeErrorIfParameterTypeMismatch(
connectionId: string,
parameterName: string,
parameterValue: any,
expectedType: string
): void {
if (typeof parameterValue !== expectedType) {
const error = new TypeError(
`The parameter "${parameterName}" should be of type "${expectedType}"`
);
logger.warning(`[${connectionId}] %O`, error);
throw error;
}
}
/**
* @internal
* @ignore
* Logs and Throws TypeError if given parameter is not of type `Long` or an array of type `Long`
* @param connectionId Id of the underlying AMQP connection used for logging
* @param parameterName Name of the parameter to type check
* @param parameterValue Value of the parameter to type check
*/
export function throwTypeErrorIfParameterNotLong(
connectionId: string,
parameterName: string,
parameterValue: any
): TypeError | undefined {
if (Array.isArray(parameterValue)) {
return throwTypeErrorIfParameterNotLongArray(connectionId, parameterName, parameterValue);
}
if (Long.isLong(parameterValue)) {
return;
}
const error = new TypeError(`The parameter "${parameterName}" should be of type "Long"`);
logger.warning(`[${connectionId}] %O`, error);
throw error;
}
/**
* @internal
* @ignore
* Logs and Throws TypeError if given parameter is not an array of type `Long`
* @param connectionId Id of the underlying AMQP connection used for logging
* @param parameterName Name of the parameter to type check
* @param parameterValue Value of the parameter to type check
*/
export function throwTypeErrorIfParameterNotLongArray(
connectionId: string,
parameterName: string,
parameterValue: any[]
): TypeError | undefined {
if (parameterValue.every((item) => Long.isLong(item))) {
return;
}
const error = new TypeError(`The parameter "${parameterName}" should be an array of type "Long"`);
logger.warning(`[${connectionId}] %O`, error);
throw error;
}
/**
* @internal
* @ignore
* Logs and Throws TypeError if given parameter is an empty string
* @param connectionId Id of the underlying AMQP connection used for logging
* @param parameterName Name of the parameter to type check
* @param parameterValue Value of the parameter to type check
*/
export function throwTypeErrorIfParameterIsEmptyString(
connectionId: string,
parameterName: string,
parameterValue: string
): TypeError | undefined {
if (parameterValue !== "") {
return;
}
const error = new TypeError(`Empty string not allowed in parameter "${parameterName}"`);
logger.warning(`[${connectionId}] %O`, error);
throw error;
}
/**
* @internal
* @ignore
* Gets error message for when an operation is not supported in ReceiveAndDelete mode
* @param failedToDo A string to add to the placeholder in the error message. Denotes the action
* that is not supported in ReceiveAndDelete mode
*/
export function getErrorMessageNotSupportedInReceiveAndDeleteMode(failedToDo: string): string {
return `Failed to ${failedToDo} as the operation is only supported in 'PeekLock' receive mode.`;
}
/**
* @internal
* @ignore
*/
export function logError(err: Error | AmqpError | undefined, ...args: any[]): void {
let l: typeof logger.info;
if (isError(err) && err.name === "AbortError") {
l = logger.info;
} else {
l = logger.warning;
}
l(...args);
logErrorStackTrace(err);
}
function isError(err: Error | AmqpError | undefined): err is Error {
return err != null && (err as any).name != null;
}