1// Copyright 2013-2020 Aerospike, Inc.
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
15package types
16
17import "fmt"
18
19// ResultCode signifies the database operation error codes.
20// The positive numbers align with the server side file proto.h.
21type ResultCode int
22
23const (
24	// Requested Rack for node/namespace was not defined in the cluster.
25	RACK_NOT_DEFINED ResultCode = -13
26
27	// Cluster has an invalid partition map, usually due to bad configuration.
28	INVALID_CLUSTER_PARTITION_MAP ResultCode = -12
29
30	// Server is not accepting requests.
31	SERVER_NOT_AVAILABLE ResultCode = -11
32
33	// Cluster Name does not match the ClientPolicy.ClusterName value.
34	CLUSTER_NAME_MISMATCH_ERROR ResultCode = -10
35
36	// Recordset has already been closed or cancelled
37	RECORDSET_CLOSED ResultCode = -9
38
39	// There were no connections available to the node in the pool, and the pool was limited
40	NO_AVAILABLE_CONNECTIONS_TO_NODE ResultCode = -8
41
42	// Data type is not supported by aerospike server.
43	TYPE_NOT_SUPPORTED ResultCode = -7
44
45	// Info Command was rejected by the server.
46	COMMAND_REJECTED ResultCode = -6
47
48	// Query was terminated by user.
49	QUERY_TERMINATED ResultCode = -5
50
51	// Scan was terminated by user.
52	SCAN_TERMINATED ResultCode = -4
53
54	// Chosen node is not currently active.
55	INVALID_NODE_ERROR ResultCode = -3
56
57	// Client parse error.
58	PARSE_ERROR ResultCode = -2
59
60	// Client serialization error.
61	SERIALIZE_ERROR ResultCode = -1
62
63	// Operation was successful.
64	OK ResultCode = 0
65
66	// Unknown server failure.
67	SERVER_ERROR ResultCode = 1
68
69	// On retrieving, touching or replacing a record that doesn't exist.
70	KEY_NOT_FOUND_ERROR ResultCode = 2
71
72	// On modifying a record with unexpected generation.
73	GENERATION_ERROR ResultCode = 3
74
75	// Bad parameter(s) were passed in database operation call.
76	PARAMETER_ERROR ResultCode = 4
77
78	// On create-only (write unique) operations on a record that already
79	// exists.
80	KEY_EXISTS_ERROR ResultCode = 5
81
82	// Bin already exists on a create-only operation.
83	BIN_EXISTS_ERROR ResultCode = 6
84
85	// Expected cluster ID was not received.
86	CLUSTER_KEY_MISMATCH ResultCode = 7
87
88	// Server has run out of memory.
89	SERVER_MEM_ERROR ResultCode = 8
90
91	// Client or server has timed out.
92	TIMEOUT ResultCode = 9
93
94	// Operation not allowed in current configuration.
95	ALWAYS_FORBIDDEN ResultCode = 10
96
97	// Partition is unavailable.
98	PARTITION_UNAVAILABLE ResultCode = 11
99
100	// Operation is not supported with configured bin type (single-bin or
101	// multi-bin).
102	BIN_TYPE_ERROR ResultCode = 12
103
104	// Record size exceeds limit.
105	RECORD_TOO_BIG ResultCode = 13
106
107	// Too many concurrent operations on the same record.
108	KEY_BUSY ResultCode = 14
109
110	// Scan aborted by server.
111	SCAN_ABORT ResultCode = 15
112
113	// Unsupported Server Feature (e.g. Scan + UDF)
114	UNSUPPORTED_FEATURE ResultCode = 16
115
116	// Bin not found on update-only operation.
117	BIN_NOT_FOUND ResultCode = 17
118
119	// Device not keeping up with writes.
120	DEVICE_OVERLOAD ResultCode = 18
121
122	// Key type mismatch.
123	KEY_MISMATCH ResultCode = 19
124
125	// Invalid namespace.
126	INVALID_NAMESPACE ResultCode = 20
127
128	// Bin name length greater than 14 characters,
129	// or maximum number of unique bin names are exceeded.
130	BIN_NAME_TOO_LONG ResultCode = 21
131
132	// Operation not allowed at this time.
133	FAIL_FORBIDDEN ResultCode = 22
134
135	// Element Not Found in CDT
136	FAIL_ELEMENT_NOT_FOUND ResultCode = 23
137
138	// Element Already Exists in CDT
139	FAIL_ELEMENT_EXISTS ResultCode = 24
140
141	// Attempt to use an Enterprise feature on a Community server or a server
142	// without the applicable feature key.
143	ENTERPRISE_ONLY ResultCode = 25
144
145	// The operation cannot be applied to the current bin value on the server.
146	OP_NOT_APPLICABLE ResultCode = 26
147
148	// The transaction was not performed because the predexp was false.
149	FILTERED_OUT ResultCode = 27
150
151	// There are no more records left for query.
152	QUERY_END ResultCode = 50
153
154	// Security type not supported by connected server.
155	SECURITY_NOT_SUPPORTED ResultCode = 51
156
157	// Administration command is invalid.
158	SECURITY_NOT_ENABLED ResultCode = 52
159
160	// Administration field is invalid.
161	SECURITY_SCHEME_NOT_SUPPORTED ResultCode = 53
162
163	// Administration command is invalid.
164	INVALID_COMMAND ResultCode = 54
165
166	// Administration field is invalid.
167	INVALID_FIELD ResultCode = 55
168
169	// Security protocol not followed.
170	ILLEGAL_STATE ResultCode = 56
171
172	// User name is invalid.
173	INVALID_USER ResultCode = 60
174
175	// User was previously created.
176	USER_ALREADY_EXISTS ResultCode = 61
177
178	// Password is invalid.
179	INVALID_PASSWORD ResultCode = 62
180
181	// Security credential is invalid.
182	EXPIRED_PASSWORD ResultCode = 63
183
184	// Forbidden password (e.g. recently used)
185	FORBIDDEN_PASSWORD ResultCode = 64
186
187	// Security credential is invalid.
188	INVALID_CREDENTIAL ResultCode = 65
189
190	// Login session expired.
191	EXPIRED_SESSION ResultCode = 66
192
193	// Role name is invalid.
194	INVALID_ROLE ResultCode = 70
195
196	// Role already exists.
197	ROLE_ALREADY_EXISTS ResultCode = 71
198
199	// Privilege is invalid.
200	INVALID_PRIVILEGE ResultCode = 72
201
202	// Invalid IP address whiltelist
203	INVALID_WHITELIST = 73
204
205	// User must be authentication before performing database operations.
206	NOT_AUTHENTICATED ResultCode = 80
207
208	// User does not posses the required role to perform the database operation.
209	ROLE_VIOLATION ResultCode = 81
210
211	// Command not allowed because sender IP address not whitelisted.
212	NOT_WHITELISTED = 82
213
214	// A user defined function returned an error code.
215	UDF_BAD_RESPONSE ResultCode = 100
216
217	// Batch functionality has been disabled.
218	BATCH_DISABLED ResultCode = 150
219
220	// Batch max requests have been exceeded.
221	BATCH_MAX_REQUESTS_EXCEEDED ResultCode = 151
222
223	// All batch queues are full.
224	BATCH_QUEUES_FULL ResultCode = 152
225
226	// Invalid GeoJSON on insert/update
227	GEO_INVALID_GEOJSON ResultCode = 160
228
229	// Secondary index already exists.
230	INDEX_FOUND ResultCode = 200
231
232	// Requested secondary index does not exist.
233	INDEX_NOTFOUND ResultCode = 201
234
235	// Secondary index memory space exceeded.
236	INDEX_OOM ResultCode = 202
237
238	// Secondary index not available.
239	INDEX_NOTREADABLE ResultCode = 203
240
241	// Generic secondary index error.
242	INDEX_GENERIC ResultCode = 204
243
244	// Index name maximum length exceeded.
245	INDEX_NAME_MAXLEN ResultCode = 205
246
247	// Maximum number of indexes exceeded.
248	INDEX_MAXCOUNT ResultCode = 206
249
250	// Secondary index query aborted.
251	QUERY_ABORTED ResultCode = 210
252
253	// Secondary index queue full.
254	QUERY_QUEUEFULL ResultCode = 211
255
256	// Secondary index query timed out on server.
257	QUERY_TIMEOUT ResultCode = 212
258
259	// Generic query error.
260	QUERY_GENERIC ResultCode = 213
261
262	// Query NetIO error on server
263	QUERY_NETIO_ERR ResultCode = 214
264
265	// Duplicate TaskId sent for the statement
266	QUERY_DUPLICATE ResultCode = 215
267
268	// UDF does not exist.
269	AEROSPIKE_ERR_UDF_NOT_FOUND ResultCode = 1301
270
271	// LUA file does not exist.
272	AEROSPIKE_ERR_LUA_FILE_NOT_FOUND ResultCode = 1302
273)
274
275// Should connection be put back into pool.
276func KeepConnection(err error) bool {
277	// if error is not an AerospikeError, Throw the connection away conservatively
278	ae, ok := err.(AerospikeError)
279	if !ok {
280		return false
281	}
282
283	switch ae.resultCode {
284	case 0, // Zero Value
285		QUERY_TERMINATED,
286		SCAN_TERMINATED,
287		PARSE_ERROR,
288		SERIALIZE_ERROR,
289		SERVER_NOT_AVAILABLE,
290		SCAN_ABORT,
291		QUERY_ABORTED,
292
293		INVALID_NODE_ERROR,
294		SERVER_MEM_ERROR,
295		TIMEOUT,
296		INDEX_OOM,
297		QUERY_TIMEOUT:
298		return false
299	default:
300		return true
301	}
302}
303
304// Return result code as a string.
305func ResultCodeToString(resultCode ResultCode) string {
306	switch ResultCode(resultCode) {
307	case RACK_NOT_DEFINED:
308		return "Requested Rack for node/namespace was not defined in the cluster."
309
310	case INVALID_CLUSTER_PARTITION_MAP:
311		return "Cluster has an invalid partition map, usually due to bad configuration."
312
313	case SERVER_NOT_AVAILABLE:
314		return "Server is not accepting requests."
315
316	case CLUSTER_NAME_MISMATCH_ERROR:
317		return "Cluster Name does not match the ClientPolicy.ClusterName value"
318
319	case RECORDSET_CLOSED:
320		return "Recordset has already been closed or cancelled."
321
322	case NO_AVAILABLE_CONNECTIONS_TO_NODE:
323		return "No available connections to the node. Connection Pool was empty, and limited to certain number of connections."
324
325	case TYPE_NOT_SUPPORTED:
326		return "Type cannot be converted to Value Type."
327
328	case COMMAND_REJECTED:
329		return "command rejected"
330
331	case QUERY_TERMINATED:
332		return "Query terminated"
333
334	case SCAN_TERMINATED:
335		return "Scan terminated"
336
337	case INVALID_NODE_ERROR:
338		return "Invalid node"
339
340	case PARSE_ERROR:
341		return "Parse error"
342
343	case SERIALIZE_ERROR:
344		return "Serialize error"
345
346	case OK:
347		return "ok"
348
349	case SERVER_ERROR:
350		return "Server error"
351
352	case KEY_NOT_FOUND_ERROR:
353		return "Key not found"
354
355	case GENERATION_ERROR:
356		return "Generation error"
357
358	case PARAMETER_ERROR:
359		return "Parameter error"
360
361	case KEY_EXISTS_ERROR:
362		return "Key already exists"
363
364	case BIN_EXISTS_ERROR:
365		return "Bin already exists"
366
367	case CLUSTER_KEY_MISMATCH:
368		return "Cluster key mismatch"
369
370	case SERVER_MEM_ERROR:
371		return "Server memory error"
372
373	case TIMEOUT:
374		return "Timeout"
375
376	case ALWAYS_FORBIDDEN:
377		return "Operation not allowed in current configuration."
378
379	case PARTITION_UNAVAILABLE:
380		return "Partition not available"
381
382	case BIN_TYPE_ERROR:
383		return "Bin type error"
384
385	case RECORD_TOO_BIG:
386		return "Record too big"
387
388	case KEY_BUSY:
389		return "Hot key"
390
391	case SCAN_ABORT:
392		return "Scan aborted"
393
394	case UNSUPPORTED_FEATURE:
395		return "Unsupported Server Feature"
396
397	case BIN_NOT_FOUND:
398		return "Bin not found"
399
400	case DEVICE_OVERLOAD:
401		return "Device overload"
402
403	case KEY_MISMATCH:
404		return "Key mismatch"
405
406	case INVALID_NAMESPACE:
407		return "Namespace not found"
408
409	case BIN_NAME_TOO_LONG:
410		return "Bin name length greater than 15 characters, or maximum number of unique bin names are exceeded"
411
412	case FAIL_FORBIDDEN:
413		return "Operation not allowed at this time"
414
415	case FAIL_ELEMENT_NOT_FOUND:
416		return "Element not found."
417
418	case FAIL_ELEMENT_EXISTS:
419		return "Element exists"
420
421	case ENTERPRISE_ONLY:
422		return "Enterprise only"
423
424	case OP_NOT_APPLICABLE:
425		return "Operation not applicable"
426
427	case FILTERED_OUT:
428		return "Transaction filtered out by predexp"
429
430	case QUERY_END:
431		return "Query end"
432
433	case SECURITY_NOT_SUPPORTED:
434		return "Security not supported"
435
436	case SECURITY_NOT_ENABLED:
437		return "Security not enabled"
438
439	case SECURITY_SCHEME_NOT_SUPPORTED:
440		return "Security scheme not supported"
441
442	case INVALID_COMMAND:
443		return "Invalid command"
444
445	case INVALID_FIELD:
446		return "Invalid field"
447
448	case ILLEGAL_STATE:
449		return "Illegal state"
450
451	case INVALID_USER:
452		return "Invalid user"
453
454	case USER_ALREADY_EXISTS:
455		return "User already exists"
456
457	case INVALID_PASSWORD:
458		return "Invalid password"
459
460	case EXPIRED_PASSWORD:
461		return "Expired password"
462
463	case FORBIDDEN_PASSWORD:
464		return "Forbidden password"
465
466	case INVALID_CREDENTIAL:
467		return "Invalid credential"
468
469	case EXPIRED_SESSION:
470		return "Login session expired"
471
472	case INVALID_ROLE:
473		return "Invalid role"
474
475	case ROLE_ALREADY_EXISTS:
476		return "Role already exists"
477
478	case INVALID_PRIVILEGE:
479		return "Invalid privilege"
480
481	case INVALID_WHITELIST:
482		return "Invalid whitelist"
483
484	case NOT_AUTHENTICATED:
485		return "Not authenticated"
486
487	case ROLE_VIOLATION:
488		return "Role violation"
489
490	case NOT_WHITELISTED:
491		return "Command not whitelisted"
492
493	case UDF_BAD_RESPONSE:
494		return "UDF returned error"
495
496	case BATCH_DISABLED:
497		return "Batch functionality has been disabled"
498
499	case BATCH_MAX_REQUESTS_EXCEEDED:
500		return "Batch max requests have been exceeded"
501
502	case BATCH_QUEUES_FULL:
503		return "All batch queues are full"
504
505	case GEO_INVALID_GEOJSON:
506		return "Invalid GeoJSON on insert/update"
507
508	case INDEX_FOUND:
509		return "Index already exists"
510
511	case INDEX_NOTFOUND:
512		return "Index not found"
513
514	case INDEX_OOM:
515		return "Index out of memory"
516
517	case INDEX_NOTREADABLE:
518		return "Index not readable"
519
520	case INDEX_GENERIC:
521		return "Index error"
522
523	case INDEX_NAME_MAXLEN:
524		return "Index name max length exceeded"
525
526	case INDEX_MAXCOUNT:
527		return "Index count exceeds max"
528
529	case QUERY_ABORTED:
530		return "Query aborted"
531
532	case QUERY_QUEUEFULL:
533		return "Query queue full"
534
535	case QUERY_TIMEOUT:
536		return "Query timeout"
537
538	case QUERY_GENERIC:
539		return "Query error"
540
541	case QUERY_NETIO_ERR:
542		return "Query NetIO error on server"
543
544	case QUERY_DUPLICATE:
545		return "Duplicate TaskId sent for the statement"
546
547	case AEROSPIKE_ERR_UDF_NOT_FOUND:
548		return "UDF does not exist."
549
550	case AEROSPIKE_ERR_LUA_FILE_NOT_FOUND:
551		return "LUA package/file does not exist."
552
553	default:
554		return fmt.Sprintf("Error code (%v) not available yet - please file an issue on github.", resultCode)
555	}
556}
557