-
Notifications
You must be signed in to change notification settings - Fork 3.8k
/
errors.proto
596 lines (527 loc) · 26.6 KB
/
errors.proto
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
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
// Copyright 2014 The Cockroach Authors.
//
// Use of this software is governed by the Business Source License
// included in the file licenses/BSL.txt.
//
// As of the Change Date specified in that file, in accordance with
// the Business Source License, use of this software will be governed
// by the Apache License, Version 2.0, included in the file
// licenses/APL.txt.
syntax = "proto2";
// NB: this file (along with most things in api.proto and metadata.proto)
// really ought to live in a ./pkg/kv/kvpb package. However, moving them
// there is a larger undertaking because import cycles require a large
// amount of refactoring. Essentially, all references to `kvpb` from the
// `roachpb` package will need to be avoided, and it takes time to make
// these changes. Second, proto renames are tricky as the paths leak into
// uses of protobuf.Any.
//
// It is for this second reason that this package was renamed preemptively
// (but not moved yet for the first reason): we use EncodedError in Error,
// and once that is released in even an alpha version, migration concerns
// arise that are not trivial to address. Since the package already has the
// correct name, the files can be moved into a newly created `kvpb` package
// at leisure.
package cockroach.kv.kvpb;
option go_package = "roachpb";
import "errorspb/errors.proto";
import "roachpb/data.proto";
import "roachpb/metadata.proto";
import "util/hlc/timestamp.proto";
import "gogoproto/gogo.proto";
// Issue #1246. Commented out because
// https://github.com/golang/protobuf/commit/d3d78384b82d449651d2435ed3
// requires that all messages implement Message, which includes
// `String() string`.
// option (gogoproto.goproto_stringer_all) = false;
// A NotLeaseHolderError indicates that the current range is not the lease
// holder. If the lease holder is known, its Replica is set in the error.
message NotLeaseHolderError {
// The replica the error originated from. Used in the error's string
// representation, if known.
optional roachpb.ReplicaDescriptor replica = 1 [(gogoproto.nullable) = false];
// The lease holder, if known.
optional roachpb.ReplicaDescriptor lease_holder = 2;
// The current lease, if known. This might be nil even when lease_holder is
// set, as sometimes one can create this error without actually knowing the
// current lease, but having a guess about who the leader is.
//
// It's possible for leases returned here to represent speculative leases, not
// actual committed leases. In this case, the lease will not have its Sequence
// set.
optional roachpb.Lease lease = 4;
optional int64 range_id = 3 [(gogoproto.nullable) = false,
(gogoproto.customname) = "RangeID", (gogoproto.casttype) = "RangeID"];
// If set, the Error() method will return this instead of composing its
// regular spiel. Useful because we reuse this error when rejecting a command
// because the lease under which its application was attempted is different
// than the lease under which it had been proposed.
optional string custom_msg = 5 [(gogoproto.nullable) = false];
}
// A NodeUnavailableError indicates that the sending gateway can
// not process requests at the time, and that the client should
// retry the request with another peer.
message NodeUnavailableError {
}
// An UnsupportedRequestError indicates that the recipient node
// does not know how to handle the type of request received.
message UnsupportedRequestError {
}
// A RangeNotFoundError indicates that a command was sent to a range
// which is not hosted on this store.
message RangeNotFoundError {
optional int64 range_id = 1 [(gogoproto.nullable) = false,
(gogoproto.customname) = "RangeID", (gogoproto.casttype) = "RangeID"];
// store_id is nonzero only if the error originated on a Store.
optional int64 store_id = 2 [(gogoproto.nullable) = false,
(gogoproto.customname) = "StoreID", (gogoproto.casttype) = "StoreID"];
}
// A RangeKeyMismatchError indicates that a command was sent to a
// range which did not contain the key(s) specified by the command.
message RangeKeyMismatchError {
optional bytes request_start_key = 1 [(gogoproto.casttype) = "Key"];
optional bytes request_end_key = 2 [(gogoproto.casttype) = "Key"];
// deprecated_mismatched_range is an older version of mismatched_range. Can go
// away in 21.1, when we don't worry about 20.1 kvservers not populating rangesInternal.
optional roachpb.RangeDescriptor deprecated_mismatched_range = 3 [(gogoproto.nullable) = false];
// deprecated_suggested_range is an older version of suggested_range. Can go
// away in 21.1, when we don't worry about 20.1 kvservers not populating
// rangesInternal.
optional roachpb.RangeDescriptor deprecated_suggested_range = 4;
// ranges contains information intended for the client's range cache. The
// server populates it with info on the range with the ID addressed by the
// client (always the first in the array) and then all other ranges
// overlapping the requested key range, or in between the addressed range and
// the requested key range.
//
// In 21.1 the customname can be removed, together with the Ranges() accessor.
repeated roachpb.RangeInfo ranges = 5 [(gogoproto.customname) = "rangesInternal",
(gogoproto.nullable) = false];
}
// A ReadWithinUncertaintyIntervalError indicates that a read at timestamp
// encountered a write within the uncertainty interval of the reader.
// The read should be retried at a higher timestamp; the timestamps contained
// within are purely informational, though typically existing_timestamp is a
// lower bound for a new timestamp at which at least the read producing
// this error would succeed on retry.
message ReadWithinUncertaintyIntervalError {
option (gogoproto.goproto_stringer) = false;
// This data below is purely informational and used to tailor the
// error message.
optional util.hlc.Timestamp read_timestamp = 1 [(gogoproto.nullable) = false];
optional util.hlc.Timestamp existing_timestamp = 2 [(gogoproto.nullable) = false];
// The remaining fields may be missing when running in clusters that have
// members at below CockroachDB v2.0.
optional util.hlc.Timestamp max_timestamp = 3;
repeated roachpb.ObservedTimestamp observed_timestamps = 4 [(gogoproto.nullable) = false];
}
// TransactionAbortedReason specifies what caused a TransactionAbortedError.
// The reasons below are not necessarily disjoint - they describe where the
// error was generated, but generally it's possible that a
// TransactionAbortedError would have been generated somewhere else if the
// client would have performed different operations.
enum TransactionAbortedReason {
option (gogoproto.goproto_enum_prefix) = false;
// For backwards compatibility.
ABORT_REASON_UNKNOWN = 0;
// A HeartbeatTxn or EndTxn(commit=true) request found an aborted transaction
// record. Another txn must have written this record - that other txn probably
// ran into one of our intents and pushed our transaction record successfully.
// Either a high-priority transaction simply pushed us or we failed to
// heartbeat for a while and another txn (of any priority) considered us
// abandoned and pushed us.
ABORT_REASON_ABORTED_RECORD_FOUND = 1;
// The client is trying to use a transaction that's already been aborted. The
// TxnCoordSender detects this. Either the client is misusing a txn, or the
// TxnCoordSender found out about the transaction being aborted async through
// the heartbeat loop.
ABORT_REASON_CLIENT_REJECT = 3;
// The txn was trying to push another and found out that it itself got aborted
// somehow while waiting for the push.
ABORT_REASON_PUSHER_ABORTED = 4;
// The txn ran into the "abort span" - it was trying to read from a range
// where it had previously laid down intents that have been cleaned up in the
// meantime because the transaction was aborted.
ABORT_REASON_ABORT_SPAN = 5;
// A request attempting to create a transaction record encountered a write
// timestamp cache entry for the txn key, and the entry identifies this
// transaction. This means that the transaction definitely committed or rolled
// back before. So, this request is either a delayed replay of some sort, or
// it raced with an async abort and lost. If a client gets this
// TransactionAbortedError (without it being wrapped in an ambiguous error),
// it must be the latter case, and the transaction can be retried.
ABORT_REASON_ALREADY_COMMITTED_OR_ROLLED_BACK_POSSIBLE_REPLAY = 6;
// A request attempting to create a transaction record is not allowed to
// proceed by the timestamp cache because it cannot be verified that the
// respective transaction record did not previously exist. As opposed to the
// case above, the timestamp cache does not have a txn id in it, but the lease
// under which the request is evaluated is newer than the transaction's
// minimum timestamp (see CanCreateTxnRecord()). A new lease wipes the
// timestamp cache, so transaction record creation is bound to fail for
// transactions that spanned a lease acquisition.
// As above, if the error has not been converted by the time it reaches a
// client, then it's not a replay.
ABORT_REASON_NEW_LEASE_PREVENTS_TXN = 8;
// Like the above, the timestamp cache rejects the creation of a transaction
// record. But there's no txn id in the ts cache, and also the lease is not
// new. The timestamp cache has lost accuracy because of a range merge or
// because of its memory limit.
// As above, if the error has not been converted by the time it reaches a
// client, then it's not a replay.
//
// TODO(andrei): We should be able to identify the range merge case by saving
// a bit more info in the timestamp cache.
ABORT_REASON_TIMESTAMP_CACHE_REJECTED = 7;
reserved 2;
}
// A TransactionAbortedError indicates that the client should retry the
// transaction (and use a different txn id, as opposed to
// TransactionRetryError). This most often happens when the transaction was
// aborted by another concurrent transaction. Upon seeing this error, the client
// is supposed to reset its Transaction proto and try the transaction again.
//
// In contrast with other errors, the Transaction that the client gets in the
// pErr carrying this ErrorDetail is not supposed to be used as is by the
// client; the ID should be checked and then attributes like the timestamp
// should be used in creating a new txn.
message TransactionAbortedError {
optional TransactionAbortedReason reason = 1 [(gogoproto.nullable) = false];
}
// A TransactionPushError indicates that the transaction could not
// continue because it encountered a write intent from another
// transaction which it was unable to push.
message TransactionPushError {
optional roachpb.Transaction pushee_txn = 1 [(gogoproto.nullable) = false];
}
// TransactionRetryReason specifies what caused a transaction retry.
enum TransactionRetryReason {
option (gogoproto.goproto_enum_prefix) = false;
// For backwards compatibility.
RETRY_REASON_UNKNOWN = 0;
// A concurrent writer finished first, causing restart.
RETRY_WRITE_TOO_OLD = 1;
// A SERIALIZABLE transaction had its timestamp moved forward.
RETRY_SERIALIZABLE = 3;
// An asynchronous write was observed to have failed.
RETRY_ASYNC_WRITE_FAILURE = 5;
// The transaction exceeded its deadline.
RETRY_COMMIT_DEADLINE_EXCEEDED = 6;
}
// A TransactionRetryError indicates that the transaction must be
// retried, usually with an increased transaction timestamp.
message TransactionRetryError {
optional TransactionRetryReason reason = 1 [(gogoproto.nullable) = false];
optional string extra_msg = 2 [(gogoproto.nullable) = false];
}
// A TransactionStatusError indicates that the transaction status is
// incompatible with the requested operation. This might mean the
// transaction has already been committed. It might also be the case
// that the request to modify the transaction failed due to a
// regression in transaction epoch or timestamp, both of which may
// only monotonically increase.
message TransactionStatusError {
optional string msg = 1 [(gogoproto.nullable) = false];
// Reason specifies what caused the error.
enum Reason {
// For backwards compatibility.
REASON_UNKNOWN = 0;
// A committed transaction record was found.
REASON_TXN_COMMITTED = 2;
reserved 1;
}
optional Reason reason = 2 [(gogoproto.nullable) = false];
}
// A WriteIntentError indicates that one or more write intent
// belonging to another transaction were encountered leading to a
// read/write or write/write conflict. The keys at which the intent
// was encountered are set, as are the txn records for the intents'
// transactions.
message WriteIntentError {
repeated roachpb.Intent intents = 1 [(gogoproto.nullable) = false];
reserved 2;
}
// A WriteTooOldError indicates that a write encountered a versioned
// value newer than its timestamp, making it impossible to rewrite
// history. The write is instead done at actual timestamp, which is
// the timestamp of the existing version+1.
//
// If a blind write request (see IsBlindWrite) returns a WriteTooOld
// error during evaluation (in pkg/kvserver/batcheval), it must also
// complete its work and return a valid result. This allows callers to
// optionally defer the WriteTooOldError until later in the transaction
// by instead bumping the transaction's write timestamp, setting the
// transaction's WriteTooOld flag, and dropping the error.
message WriteTooOldError {
optional util.hlc.Timestamp timestamp = 1 [(gogoproto.nullable) = false];
optional util.hlc.Timestamp actual_timestamp = 2 [(gogoproto.nullable) = false];
}
// An OpRequiresTxnError indicates that a command required to be
// carried out in a transactional context but was not.
// For example, a Scan which spans ranges requires a transaction.
// The operation should be retried inside of a transaction.
message OpRequiresTxnError {
}
// A ConditionFailedError indicates that the expected value
// of a ConditionalPutRequest was not found, either
// because it was missing or was not equal. The error will
// contain the actual value found.
message ConditionFailedError {
optional roachpb.Value actual_value = 1;
}
// A LeaseRejectedError indicates that the requested replica could
// not acquire the desired lease because of an existing range lease.
message LeaseRejectedError {
optional string message = 1 [(gogoproto.nullable) = false];
optional roachpb.Lease requested = 2 [(gogoproto.nullable) = false];
optional roachpb.Lease existing = 3 [(gogoproto.nullable) = false];
}
// An AmbiguousResultError indicates that a request may have succeeded or
// failed, but the response was not received and the final result is ambiguous.
message AmbiguousResultError {
optional string message = 1 [(gogoproto.nullable) = false];
// This can be set to give extra information about which error was converted
// into an AmbiguousResultError. Useful for tests.
optional Error wrapped_err = 2;
}
// A RaftGroupDeletedError indicates a raft group has been deleted for
// the replica.
message RaftGroupDeletedError {
}
// A ReplicaCorruptionError indicates that the replica has experienced
// an error which puts its integrity at risk.
message ReplicaCorruptionError {
optional string error_msg = 1 [(gogoproto.nullable) = false];
// processed indicates that the error has been taken into account and
// necessary steps will be taken. For now, required for testing.
optional bool processed = 2 [(gogoproto.nullable) = false];
}
// ReplicaTooOldError is sent in response to a raft message when the
// recipient of the raft message believes the sender of the raft
// message to have been removed from the raft group
message ReplicaTooOldError {
// replica_id is the ID of the replica that is too old.
optional int32 replica_id = 1 [(gogoproto.nullable) = false,
(gogoproto.customname) = "ReplicaID", (gogoproto.casttype) = "ReplicaID"];
}
// A StoreNotFoundError indicates that a command was sent to a store
// which is not hosted on this node.
message StoreNotFoundError {
optional int64 store_id = 1 [(gogoproto.nullable) = false,
(gogoproto.customname) = "StoreID", (gogoproto.casttype) = "StoreID"];
}
// UnhandledRetryableError tells the recipient that a KV request must be
// retried. In case the request was transactional, the whole transaction needs
// to be retried. This is returned generally as a result of a transaction
// conflict.
//
// This error is generated by pErr.GoError() in case of a retryable
// error (other than TransactionRetryWithProtoRefreshError). For transactional
// requests, the TxnCoordSender handles retryable pErrs and transforms
// them into TransactionRetryWithProtoRefreshError. For non-transactional requests,
// this error will be observed by layers above the TxnCoordSender.
message UnhandledRetryableError {
option (gogoproto.goproto_stringer) = false;
// The underlying storage error that is being marshaled.
// pErr.TransactionRestart is expected to be set, and the error
// detail is one of the retryable ones.
optional Error pErr = 1 [(gogoproto.nullable) = false];
}
// TransactionRetryWithProtoRefreshError is an error detail representing a retryable error
// that has been "handled" by the TxnCoordSender. This error is produced by the
// TxnCoordSender and is only produced for transactional requests.
//
// It contains the final form of the Transaction proto that should be used on
// next attempts. After being produced by the TxnCoordSender, this error is
// handled first by the client.Txn, which uses the Transaction inside to update
// its state, and then passed along to SQL in a pErr (through the
// client.Sender() interface).
message TransactionRetryWithProtoRefreshError {
// A user-readable message.
optional string msg = 1 [(gogoproto.nullable) = false];
// The ID of the transaction being restarted. The client is supposed to check
// this against the ID of its transaction and make sure the retryable error
// is meant for its level and didn't escape from some inner transaction.
optional bytes txn_id = 2 [
(gogoproto.customtype) = "github.com/cockroachdb/cockroach/pkg/util/uuid.UUID",
(gogoproto.customname) = "TxnID",
(gogoproto.nullable) = false];
// The Transaction that should be used by next attempts. Depending on the
// original cause of this method, this can either be the same Transaction as
// before, but with an incremented epoch and timestamp, or a completely new
// Transaction.
optional roachpb.Transaction transaction = 3 [(gogoproto.nullable) = false];
}
// TxnAlreadyEncounteredErrorError indicates that an operation tried to use a
// transaction that already received an error from a previous request. Once that
// happens, client.Txn rejects future requests.
message TxnAlreadyEncounteredErrorError{
// prev_error is the message from the error that the txn encountered
// previously.
optional string prev_error = 1 [(gogoproto.nullable) = false];
}
// An IntegerOverflowError indicates that an operation was aborted because
// it would have caused an integeter overflow.
message IntegerOverflowError {
optional bytes key = 1 [(gogoproto.casttype) = "Key"];
optional int64 current_value = 2 [(gogoproto.nullable) = false];
optional int64 increment_value = 3 [(gogoproto.nullable) = false];
}
// A BatchTimestampBeforeGCError indicates that a request's timestamp was
// before the GC threshold.
message BatchTimestampBeforeGCError {
optional util.hlc.Timestamp Timestamp = 1 [(gogoproto.nullable) = false];
optional util.hlc.Timestamp Threshold = 2 [(gogoproto.nullable) = false];
}
// An IntentMissingError indicates that a QueryIntent request expected
// an intent to be present at its specified key but the intent was
// not there.
message IntentMissingError {
// The non-matching intent that was found at that key, if any.
optional roachpb.Intent wrong_intent = 1;
// The key where the intent was expected.
optional bytes key = 2 [(gogoproto.casttype) = "Key"];
}
// A MergeInProgressError indicates that the request could not be completed
// because the replica is being merged into its left-hand neighbor. The request
// should be resubmitted after the merge completes.
//
// This error is handled by the Store and should not escape to higher levels.
message MergeInProgressError {
}
// A RangeFeedRetryError indicates that a rangefeed was disconnected, often
// because of a range lifecycle event, and can be retried.
message RangeFeedRetryError {
// Reason specifies what caused the error.
enum Reason {
// The replica was removed from its store.
REASON_REPLICA_REMOVED = 0;
// The range was split in two.
REASON_RANGE_SPLIT = 1;
// The range was merged into another.
REASON_RANGE_MERGED = 2;
// A Raft snapshot applied on the replica.
REASON_RAFT_SNAPSHOT = 3;
// A Raft command was missing a logical operation log.
REASON_LOGICAL_OPS_MISSING = 4;
// The consumer was processing events too slowly to keep up with live raft
// events.
REASON_SLOW_CONSUMER = 5;
}
optional Reason reason = 1 [(gogoproto.nullable) = false];
}
// A IndeterminateCommitError indicates that a transaction was encountered with
// a STAGING status. In this state, it is unclear by observing the transaction
// record alone whether the transaction should be committed or aborted. To make
// this determination, the transaction recovery process must be initiated. This
// process makes a ruling on the final state of the transaction based on the
// outcome of its in-flight writes at the time of staging.
message IndeterminateCommitError {
optional roachpb.Transaction staging_txn = 1 [(gogoproto.nullable) = false];
}
// ParentAbortedError indicates that the parent transaction of a child has been
// aborted while the child is waiting to push another transaction. There is no
// reason for the child to proceed if the parent is already aborted. We cannot
// just use a TransactionAbortedError as the TxnCoordSender would translate
// that into a TransactionRetryWithProtoRefreshError which is not the desired
// behavior.
message ParentAbortedError {
optional roachpb.Transaction parent_txn = 1 [(gogoproto.nullable) = false];
}
// ErrorDetail is a union type containing all available errors.
message ErrorDetail {
reserved 15, 19, 20, 21, 22, 23, 24, 25, 29, 30, 33;
oneof value {
NotLeaseHolderError not_lease_holder = 1;
RangeNotFoundError range_not_found = 2;
RangeKeyMismatchError range_key_mismatch = 3;
ReadWithinUncertaintyIntervalError read_within_uncertainty_interval = 4;
TransactionAbortedError transaction_aborted = 5;
TransactionPushError transaction_push = 6;
TransactionRetryError transaction_retry = 7;
TransactionStatusError transaction_status = 8;
WriteIntentError write_intent = 9;
WriteTooOldError write_too_old = 10;
OpRequiresTxnError op_requires_txn = 11;
ConditionFailedError condition_failed = 12;
LeaseRejectedError lease_rejected = 13;
NodeUnavailableError node_unavailable = 14;
// TODO(kaneda): Following three are added to preserve the type when
// converting Go errors from/to proto Errors. Revisit this design.
RaftGroupDeletedError raft_group_deleted = 16;
ReplicaCorruptionError replica_corruption = 17;
ReplicaTooOldError replica_too_old = 18;
AmbiguousResultError ambiguous_result = 26;
StoreNotFoundError store_not_found = 27;
// The following three are ErrorDetails (and proto messages) because they
// needs to be communicated from the TxnCoordSender and Txn to the upper
// layers through the Sender interface.
TransactionRetryWithProtoRefreshError transaction_retry_with_proto_refresh = 28;
IntegerOverflowError integer_overflow = 31;
UnsupportedRequestError unsupported_request = 32;
BatchTimestampBeforeGCError timestamp_before = 34;
TxnAlreadyEncounteredErrorError txn_already_encountered_error = 35;
IntentMissingError intent_missing = 36;
MergeInProgressError merge_in_progress = 37;
RangeFeedRetryError rangefeed_retry = 38;
IndeterminateCommitError indeterminate_commit = 39;
ParentAbortedError parent_aborted = 40;
}
}
// TransactionRestart indicates how an error should be handled in a
// transactional context.
enum TransactionRestart {
// NONE (the default) is used for errors which have no effect on the
// transaction state. That is, a transactional operation which receives such
// an error is still PENDING and does not need to restart (at least not as a
// result of the error). Examples are a CPut whose condition wasn't met, or
// a spurious RPC error.
NONE = 0;
// BACKOFF is for errors that can retried by restarting the transaction
// after an exponential backoff.
// Note: Deprecated.
BACKOFF = 1;
// IMMEDIATE is for errors that can be retried by restarting the
// transaction immediately.
IMMEDIATE = 2;
}
// ErrPosition describes the position of an error in a Batch. A simple nullable
// primitive field would break compatibility with proto3, where primitive fields
// are no longer allowed to be nullable.
message ErrPosition {
optional int32 index = 1 [(gogoproto.nullable) = false];
}
// Error is a generic representation including a string message
// and information about retryability.
message Error {
option (gogoproto.goproto_stringer) = false;
// message is a human-readable error message.
//
// DEPRECATED.
optional string message = 1 [(gogoproto.nullable) = false, (gogoproto.customname) = "deprecatedMessage"];
// If transaction_restart is not NONE, the error condition may be handled by
// restarting the transaction.
//
// DEPRECATED.
optional TransactionRestart transaction_restart = 3 [(gogoproto.nullable) = false, (gogoproto.customname) = "deprecatedTransactionRestart"];
// An optional updated transaction. This is to be used by the client in case
// of retryable errors.
//
// Not to be accessed directly - use Error.GetTxn() and Error.SetTxn().
optional roachpb.Transaction unexposed_txn = 4;
// Node at which the error was generated (zero if does not apply).
optional int32 origin_node = 5 [(gogoproto.nullable) = false, (gogoproto.casttype) = "NodeID"];
// If an ErrorDetail is present, it may contain additional structured data
// about the error.
//
// DEPRECATED - consult encoded_error instead.
optional ErrorDetail detail = 6 [(gogoproto.nullable) = false, (gogoproto.customname) = "deprecatedDetail"];
// encoded_error is the Go error that caused this Error.
optional errorspb.EncodedError encoded_error = 9 [(gogoproto.nullable) = false];
// The index, if given, contains the index of the request (in the batch)
// whose execution caused the error.
optional ErrPosition index = 7;
// now is the current time at the node sending the response,
// which can be used by the receiver to update its local HLC.
optional util.hlc.Timestamp now = 8 [(gogoproto.nullable) = false];
reserved 2;
}