1use serde::Deserialize;
20use std::error::Error as StdError;
21use std::fmt::{Display, Formatter, Pointer};
22use std::io;
23
24use crate::memdx::opcode::OpCode;
25use crate::memdx::status::Status;
26use crate::tracingcomponent::MetricsName;
27
28pub type Result<T> = std::result::Result<T, Error>;
29
30#[derive(Debug, PartialEq)]
31pub struct Error {
32 inner: ErrorImpl,
33}
34
35impl Error {
36 pub(crate) fn new_protocol_error(msg: impl Into<String>) -> Self {
37 Self {
38 inner: ErrorImpl {
39 kind: Box::new(ErrorKind::Protocol { msg: msg.into() }),
40 source: None,
41 },
42 }
43 }
44
45 pub(crate) fn new_decompression_error() -> Self {
46 Self {
47 inner: ErrorImpl {
48 kind: Box::new(ErrorKind::Decompression {}),
49 source: None,
50 },
51 }
52 }
53
54 pub(crate) fn new_message_error(msg: impl Into<String>) -> Self {
55 Self {
56 inner: ErrorImpl {
57 kind: Box::new(ErrorKind::Message(msg.into())),
58 source: None,
59 },
60 }
61 }
62
63 pub(crate) fn new_cancelled_error(cancellation_kind: CancellationErrorKind) -> Self {
64 Self {
65 inner: ErrorImpl {
66 kind: Box::new(ErrorKind::Cancelled(cancellation_kind)),
67 source: None,
68 },
69 }
70 }
71
72 pub(crate) fn new_invalid_argument_error(
73 msg: impl Into<String>,
74 arg: impl Into<Option<String>>,
75 ) -> Self {
76 Self {
77 inner: ErrorImpl {
78 kind: Box::new(ErrorKind::InvalidArgument {
79 msg: msg.into(),
80 arg: arg.into(),
81 }),
82 source: None,
83 },
84 }
85 }
86
87 pub(crate) fn new_connection_failed_error(
88 reason: impl Into<String>,
89 source: Box<io::Error>,
90 ) -> Self {
91 Self {
92 inner: ErrorImpl {
93 kind: Box::new(ErrorKind::ConnectionFailed { msg: reason.into() }),
94 source: Some(source),
95 },
96 }
97 }
98
99 pub(crate) fn new_dispatch_error(opaque: u32, op_code: OpCode, source: Box<Error>) -> Self {
100 Self {
101 inner: ErrorImpl {
102 kind: Box::new(ErrorKind::Dispatch { opaque, op_code }),
103 source: Some(source),
104 },
105 }
106 }
107
108 pub(crate) fn new_close_error(msg: String, source: Box<Error>) -> Self {
109 Self {
110 inner: ErrorImpl {
111 kind: Box::new(ErrorKind::Close { msg }),
112 source: Some(source),
113 },
114 }
115 }
116
117 pub fn has_server_config(&self) -> Option<&Vec<u8>> {
118 if let ErrorKind::Server(ServerError { config, .. }) = self.inner.kind.as_ref() {
119 config.as_ref()
120 } else {
121 None
122 }
123 }
124
125 pub fn has_server_error_context(&self) -> Option<&Vec<u8>> {
126 if let ErrorKind::Server(ServerError { context, .. }) = self.inner.kind.as_ref() {
127 context.as_ref()
128 } else if let ErrorKind::Resource(ResourceError { cause, .. }) = self.inner.kind.as_ref() {
129 cause.context.as_ref()
130 } else {
131 None
132 }
133 }
134
135 pub fn has_opaque(&self) -> Option<u32> {
136 let inner_kind = self.inner.kind.as_ref();
137 if let ErrorKind::Server(ServerError { opaque, .. }) = inner_kind {
138 Some(*opaque)
139 } else if let ErrorKind::Resource(e) = inner_kind {
140 Some(e.cause.opaque)
141 } else if let ErrorKind::Dispatch { opaque, .. } = inner_kind {
142 Some(*opaque)
143 } else {
144 None
145 }
146 }
147
148 pub fn is_cancellation_error(&self) -> bool {
149 matches!(self.inner.kind.as_ref(), ErrorKind::Cancelled { .. })
150 }
151
152 pub fn is_dispatch_error(&self) -> bool {
153 matches!(self.inner.kind.as_ref(), ErrorKind::Dispatch { .. })
154 }
155
156 pub fn is_server_error_kind(&self, kind: ServerErrorKind) -> bool {
157 match self.inner.kind.as_ref() {
158 ErrorKind::Server(e) => e.kind == kind,
159 ErrorKind::Resource(e) => e.cause.kind == kind,
160 _ => false,
161 }
162 }
163
164 pub fn kind(&self) -> &ErrorKind {
165 &self.inner.kind
166 }
167
168 pub(crate) fn with<C: Into<Source>>(mut self, source: C) -> Error {
169 self.inner.source = Some(source.into());
170 self
171 }
172}
173
174type Source = Box<dyn StdError + Send + Sync>;
175
176#[derive(Debug)]
177struct ErrorImpl {
178 kind: Box<ErrorKind>,
179 source: Option<Source>,
180}
181
182impl PartialEq for ErrorImpl {
183 fn eq(&self, other: &Self) -> bool {
184 self.kind == other.kind
185 }
186}
187
188impl Display for Error {
189 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
190 write!(f, "{}", self.inner.kind)
191 }
192}
193
194impl StdError for Error {
195 fn source(&self) -> Option<&(dyn StdError + 'static)> {
196 self.inner
197 .source
198 .as_ref()
199 .map(|cause| &**cause as &(dyn StdError + 'static))
200 }
201}
202
203#[derive(Debug, Clone, PartialEq)]
204#[non_exhaustive]
205pub enum ErrorKind {
206 Server(ServerError),
207 Resource(ResourceError),
208 #[non_exhaustive]
209 Dispatch {
210 opaque: u32,
211 op_code: OpCode,
212 },
213 #[non_exhaustive]
214 Close {
215 msg: String,
216 },
217 #[non_exhaustive]
218 Protocol {
219 msg: String,
220 },
221 Cancelled(CancellationErrorKind),
222 #[non_exhaustive]
223 ConnectionFailed {
224 msg: String,
225 },
226 Io,
227 #[non_exhaustive]
228 InvalidArgument {
229 msg: String,
230 arg: Option<String>,
231 },
232 Decompression,
233 Message(String),
234}
235
236impl Display for ErrorKind {
237 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
238 match self {
239 ErrorKind::Server(e) => write!(f, "{e}"),
240 ErrorKind::Resource(e) => write!(f, "{e}"),
241 ErrorKind::Dispatch { opaque, op_code } => {
242 write!(f, "dispatch failed: opaque: {opaque}, op_code: {op_code}")
243 }
244 ErrorKind::Close { msg } => {
245 write!(f, "close error {msg}")
246 }
247 ErrorKind::Protocol { msg } => {
248 write!(f, "{msg}")
249 }
250 ErrorKind::Cancelled(kind) => {
251 write!(f, "request cancelled: {kind}")
252 }
253 ErrorKind::ConnectionFailed { msg } => {
254 write!(f, "connection failed {msg}")
255 }
256 ErrorKind::Io => {
257 write!(f, "connection error")
258 }
259 ErrorKind::InvalidArgument { msg, arg } => {
260 let base_msg = format!("invalid argument: {msg}");
261 if let Some(arg) = arg {
262 write!(f, "{base_msg}, arg: {arg}")
263 } else {
264 write!(f, "{base_msg}")
265 }
266 }
267 ErrorKind::Decompression => write!(f, "decompression error"),
268 ErrorKind::Message(msg) => write!(f, "{msg}"),
269 }
270 }
271}
272
273#[derive(Clone, Debug, PartialEq, Eq)]
274#[non_exhaustive]
275pub struct ResourceError {
276 cause: ServerError,
277 scope_name: String,
278 collection_name: String,
279}
280
281impl StdError for ResourceError {}
282
283impl ResourceError {
284 pub(crate) fn new(
285 cause: ServerError,
286 scope_name: impl Into<String>,
287 collection_name: impl Into<String>,
288 ) -> Self {
289 Self {
290 cause,
291 scope_name: scope_name.into(),
292 collection_name: collection_name.into(),
293 }
294 }
295
296 pub fn cause(&self) -> &ServerError {
297 &self.cause
298 }
299
300 pub fn scope_name(&self) -> &str {
301 &self.scope_name
302 }
303
304 pub fn collection_name(&self) -> &str {
305 &self.collection_name
306 }
307}
308
309impl Display for ResourceError {
310 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
311 write!(
312 f,
313 "Resource error: {}, scope: {}, collection: {}",
314 self.cause, self.scope_name, self.collection_name
315 )
316 }
317}
318
319#[derive(Clone, Debug, PartialEq, Eq)]
320#[non_exhaustive]
321pub struct ServerError {
322 kind: ServerErrorKind,
323 config: Option<Vec<u8>>,
324 context: Option<Vec<u8>>,
325 op_code: OpCode,
326 status: Status,
327 opaque: u32,
328}
329
330impl StdError for ServerError {}
331
332impl Display for ServerError {
333 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
334 let mut base_msg = format!(
335 "Server error: {}, status: 0x{:02x}, opcode: {}, opaque: {}",
336 self.kind,
337 u16::from(self.status),
338 self.op_code,
339 self.opaque
340 );
341
342 if let Some(context) = &self.context {
343 if let Some(parsed) = Self::parse_context(context) {
344 base_msg.push_str(" (");
345 if let Some(text) = &parsed.text {
346 base_msg.push_str(&format!("context: {text}, "));
347 }
348
349 if let Some(error_ref) = &parsed.error_ref {
350 base_msg.push_str(&format!("error_ref: {error_ref}"));
351 }
352 base_msg.push(')');
353 }
354 }
355
356 write!(f, "{base_msg}")
357 }
358}
359
360impl ServerError {
361 pub(crate) fn new(kind: ServerErrorKind, op_code: OpCode, status: Status, opaque: u32) -> Self {
362 Self {
363 kind,
364 config: None,
365 context: None,
366 op_code,
367 status,
368 opaque,
369 }
370 }
371
372 pub(crate) fn with_context(mut self, context: Vec<u8>) -> Self {
373 self.context = Some(context);
374 self
375 }
376
377 pub(crate) fn with_config(mut self, config: Vec<u8>) -> Self {
378 self.config = Some(config);
379 self
380 }
381
382 pub fn kind(&self) -> &ServerErrorKind {
383 &self.kind
384 }
385
386 pub fn config(&self) -> Option<&Vec<u8>> {
387 self.config.as_ref()
388 }
389
390 pub fn context(&self) -> Option<&Vec<u8>> {
391 self.context.as_ref()
392 }
393
394 pub fn op_code(&self) -> OpCode {
395 self.op_code
396 }
397
398 pub fn status(&self) -> Status {
399 self.status
400 }
401
402 pub fn opaque(&self) -> u32 {
403 self.opaque
404 }
405
406 pub fn parse_context(context: &[u8]) -> Option<ServerErrorContext> {
407 if context.is_empty() {
408 return None;
409 }
410
411 let context_json: ServerErrorContextJson = match serde_json::from_slice(context) {
412 Ok(c) => c,
413 Err(_) => {
414 return None;
415 }
416 };
417
418 let text = context_json.error.context;
419
420 let error_ref = context_json.error.error_ref;
421
422 let manifest_rev = context_json
423 .manifest_rev
424 .map(|manifest_rev| u64::from_str_radix(&manifest_rev, 16).unwrap_or_default());
425
426 Some(ServerErrorContext {
427 text,
428 error_ref,
429 manifest_rev,
430 })
431 }
432}
433
434#[derive(Clone, Debug, PartialEq, Eq)]
435#[non_exhaustive]
436pub struct ServerErrorContext {
437 pub text: Option<String>,
438 pub error_ref: Option<String>,
439 pub manifest_rev: Option<u64>,
440}
441
442#[derive(Clone, Debug, Eq, Hash, PartialEq)]
443#[non_exhaustive]
444pub enum ServerErrorKind {
445 KeyNotFound,
446 KeyExists,
447 TooBig,
448 NotStored,
449 BadDelta,
450 NotMyVbucket,
451 NoBucket,
452 Locked,
453 NotLocked,
454 Auth { msg: String },
455 RangeError,
456 Access,
457 RateLimitedNetworkIngress,
458 RateLimitedNetworkEgress,
459 RateLimitedMaxConnections,
460 RateLimitedMaxCommands,
461 RateLimitedScopeSizeLimitExceeded,
462 UnknownCommand,
463 NotSupported,
464 InternalError,
465 Busy,
466 TmpFail,
467 UnknownCollectionID,
468 UnknownScopeName,
469 UnknownCollectionName,
470 DurabilityInvalid,
471 DurabilityImpossible,
472 SyncWriteInProgress,
473 SyncWriteAmbiguous,
474 SyncWriteRecommitInProgress,
475 RangeScanCancelled,
476 RangeScanVBUUIDNotEqual,
477 InvalidArgs,
478 AuthStale,
479
480 ConfigNotSet,
481 UnknownBucketName,
482 CasMismatch,
483
484 Subdoc { error: SubdocError },
485
486 UnknownStatus { status: Status },
487}
488
489impl Display for ServerErrorKind {
490 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
491 match self {
492 ServerErrorKind::NotMyVbucket => write!(f, "not my vbucket"),
493 ServerErrorKind::KeyExists => write!(f, "key exists"),
494 ServerErrorKind::NotStored => write!(f, "key not stored"),
495 ServerErrorKind::KeyNotFound => write!(f, "key not found"),
496 ServerErrorKind::TmpFail => write!(f, "temporary failure"),
497 ServerErrorKind::CasMismatch => write!(f, "cas mismatch"),
498 ServerErrorKind::Locked => write!(f, "locked"),
499 ServerErrorKind::NotLocked => write!(f, "not locked"),
500 ServerErrorKind::TooBig => write!(f, "too big"),
501 ServerErrorKind::UnknownCollectionID => write!(f, "unknown collection id"),
502 ServerErrorKind::NoBucket => write!(f, "no bucket selected"),
503 ServerErrorKind::UnknownBucketName => write!(f, "unknown bucket name"),
504 ServerErrorKind::Access => write!(f, "access error"),
505 ServerErrorKind::Auth { msg } => write!(f, "auth error {msg}"),
506 ServerErrorKind::ConfigNotSet => write!(f, "config not set"),
507 ServerErrorKind::UnknownScopeName => write!(f, "scope name unknown"),
508 ServerErrorKind::UnknownCollectionName => write!(f, "collection name unknown"),
509 ServerErrorKind::Subdoc { error } => write!(f, "{error}"),
510 ServerErrorKind::UnknownStatus { status } => {
511 write!(f, "server status unexpected for operation: {status}")
512 }
513 ServerErrorKind::BadDelta => write!(f, "bad delta"),
514 ServerErrorKind::UnknownCommand => write!(f, "unknown command"),
515 ServerErrorKind::RangeError => write!(f, "range error"),
516 ServerErrorKind::RateLimitedNetworkIngress => {
517 write!(f, "rate limited: network ingress")
518 }
519 ServerErrorKind::RateLimitedNetworkEgress => write!(f, "rate limited: network egress"),
520 ServerErrorKind::RateLimitedMaxConnections => {
521 write!(f, "rate limited: max connections")
522 }
523 ServerErrorKind::RateLimitedMaxCommands => write!(f, "rate limited: max commands"),
524 ServerErrorKind::RateLimitedScopeSizeLimitExceeded => {
525 write!(f, "rate limited: scope size limit exceeded")
526 }
527 ServerErrorKind::NotSupported => write!(f, "not supported"),
528 ServerErrorKind::InternalError => write!(f, "internal error"),
529 ServerErrorKind::Busy => write!(f, "busy"),
530 ServerErrorKind::DurabilityInvalid => write!(f, "durability invalid"),
531 ServerErrorKind::DurabilityImpossible => write!(f, "durability impossible"),
532 ServerErrorKind::SyncWriteInProgress => write!(f, "sync write in progress"),
533 ServerErrorKind::SyncWriteAmbiguous => write!(f, "sync write ambiguous"),
534 ServerErrorKind::SyncWriteRecommitInProgress => {
535 write!(f, "sync write recommit in progress")
536 }
537 ServerErrorKind::RangeScanCancelled => write!(f, "range scan cancelled"),
538 ServerErrorKind::RangeScanVBUUIDNotEqual => write!(f, "range scan vbUUID not equal"),
539 ServerErrorKind::InvalidArgs => write!(f, "invalid args"),
540 ServerErrorKind::AuthStale => write!(f, "auth stale"),
541 }
542 }
543}
544
545#[derive(Clone, Debug, PartialEq, Eq, Hash)]
546#[non_exhaustive]
547pub struct SubdocError {
548 kind: SubdocErrorKind,
549 op_index: Option<u8>,
550}
551
552impl StdError for SubdocError {}
553
554impl SubdocError {
555 pub(crate) fn new(kind: SubdocErrorKind, op_index: impl Into<Option<u8>>) -> Self {
556 Self {
557 kind,
558 op_index: op_index.into(),
559 }
560 }
561
562 pub fn is_error_kind(&self, kind: SubdocErrorKind) -> bool {
563 self.kind == kind
564 }
565
566 pub fn kind(&self) -> &SubdocErrorKind {
567 &self.kind
568 }
569
570 pub fn op_index(&self) -> Option<u8> {
571 self.op_index
572 }
573}
574
575impl Display for SubdocError {
576 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
577 if let Some(op_index) = self.op_index {
578 let base_msg = format!("Subdoc error: {}, op_index: {}", self.kind, op_index);
579 write!(f, "{base_msg}")
580 } else {
581 let base_msg = format!("Subdoc error: {}", self.kind);
582 write!(f, "{base_msg}")
583 }
584 }
585}
586
587#[derive(Clone, Debug, Eq, Hash, PartialEq)]
588#[non_exhaustive]
589pub enum SubdocErrorKind {
590 PathNotFound,
591 PathMismatch,
592 PathInvalid,
593 PathTooBig,
594 DocTooDeep,
595 CantInsert,
596 NotJSON,
597 BadRange,
598 BadDelta,
599 PathExists,
600 ValueTooDeep,
601 InvalidCombo,
602 XattrInvalidFlagCombo,
603 XattrInvalidKeyCombo,
604 XattrUnknownMacro,
605 XattrUnknownVAttr,
606 XattrCannotModifyVAttr,
607 InvalidXattrOrder,
608 XattrUnknownVattrMacro,
609 CanOnlyReviveDeletedDocuments,
610 DeletedDocumentCantHaveValue,
611 UnknownStatus { status: Status },
612}
613
614impl Display for SubdocErrorKind {
615 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
616 match self {
617 SubdocErrorKind::PathNotFound => write!(f, "subdoc path not found"),
618 SubdocErrorKind::PathMismatch => write!(f, "subdoc path mismatch"),
619 SubdocErrorKind::PathInvalid => write!(f, "subdoc path invalid"),
620 SubdocErrorKind::PathTooBig => write!(f, "subdoc path too big"),
621 SubdocErrorKind::DocTooDeep => write!(f, "subdoc doc too deep"),
622 SubdocErrorKind::CantInsert => write!(f, "subdoc can't insert"),
623 SubdocErrorKind::NotJSON => write!(f, "subdoc not JSON"),
624 SubdocErrorKind::BadRange => write!(f, "subdoc bad range"),
625 SubdocErrorKind::BadDelta => write!(f, "subdoc bad delta"),
626 SubdocErrorKind::PathExists => write!(f, "subdoc path exists"),
627 SubdocErrorKind::ValueTooDeep => write!(f, "subdoc value too deep"),
628 SubdocErrorKind::InvalidCombo => write!(f, "subdoc invalid combo"),
629 SubdocErrorKind::XattrInvalidFlagCombo => write!(f, "subdoc xattr invalid flag combo"),
630 SubdocErrorKind::XattrInvalidKeyCombo => write!(f, "subdoc xattr invalid key combo"),
631 SubdocErrorKind::XattrUnknownMacro => write!(f, "subdoc xattr unknown macro"),
632 SubdocErrorKind::XattrUnknownVAttr => write!(f, "subdoc xattr unknown vattr"),
633 SubdocErrorKind::XattrCannotModifyVAttr => {
634 write!(f, "subdoc xattr cannot modify vattr")
635 }
636 SubdocErrorKind::InvalidXattrOrder => write!(f, "subdoc invalid xattr order"),
637 SubdocErrorKind::XattrUnknownVattrMacro => {
638 write!(f, "subdoc xattr unknown vattr macro")
639 }
640 SubdocErrorKind::CanOnlyReviveDeletedDocuments => {
641 write!(f, "subdoc can only revive deleted documents")
642 }
643 SubdocErrorKind::DeletedDocumentCantHaveValue => {
644 write!(f, "subdoc deleted document can't have value")
645 }
646 SubdocErrorKind::UnknownStatus { status } => write!(
647 f,
648 "subdoc unknown status unexpected for operation: {status}"
649 ),
650 }
651 }
652}
653
654#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
655#[non_exhaustive]
656pub enum CancellationErrorKind {
657 Timeout,
658 RequestCancelled,
659 ClosedInFlight,
660}
661
662impl Display for CancellationErrorKind {
663 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
664 let txt = match self {
665 CancellationErrorKind::Timeout => "Timeout",
666 CancellationErrorKind::RequestCancelled => "Request cancelled",
667 CancellationErrorKind::ClosedInFlight => "Closed in flight",
668 };
669
670 write!(f, "{txt}")
671 }
672}
673
674impl<E> From<E> for Error
675where
676 ErrorKind: From<E>,
677{
678 fn from(err: E) -> Self {
679 Self {
680 inner: ErrorImpl {
681 kind: Box::new(ErrorKind::from(err)),
682 source: None,
683 },
684 }
685 }
686}
687
688impl From<ServerError> for Error {
689 fn from(value: ServerError) -> Self {
690 Self {
691 inner: ErrorImpl {
692 kind: Box::new(ErrorKind::Server(value)),
693 source: None,
694 },
695 }
696 }
697}
698
699impl From<ResourceError> for Error {
700 fn from(value: ResourceError) -> Self {
701 Self {
702 inner: ErrorImpl {
703 kind: Box::new(ErrorKind::Resource(value)),
704 source: None,
705 },
706 }
707 }
708}
709
710impl From<io::Error> for Error {
711 fn from(value: io::Error) -> Self {
712 Self {
713 inner: ErrorImpl {
714 kind: Box::new(ErrorKind::Io),
715 source: Some(Box::new(value)),
716 },
717 }
718 }
719}
720
721#[derive(Deserialize, Clone, Debug, PartialEq, Eq, Default)]
722struct ServerErrorContextJsonContext {
723 #[serde(alias = "context")]
724 context: Option<String>,
725 #[serde(alias = "ref")]
726 pub error_ref: Option<String>,
727}
728
729#[derive(Deserialize, Clone, Debug, PartialEq, Eq)]
730struct ServerErrorContextJson {
731 #[serde(alias = "error", default)]
732 error: ServerErrorContextJsonContext,
733 #[serde(alias = "manifest_uid")]
734 pub manifest_rev: Option<String>,
735}
736
737impl MetricsName for Error {
738 fn metrics_name(&self) -> &'static str {
739 self.kind().metrics_name()
740 }
741}
742
743impl MetricsName for ErrorKind {
744 fn metrics_name(&self) -> &'static str {
745 match self {
746 ErrorKind::Server(err) => err.kind().metrics_name(),
747 ErrorKind::Resource(err) => err.cause().kind().metrics_name(),
748 ErrorKind::Dispatch { .. } => "memdx.Dispatch",
749 ErrorKind::Close { .. } => "memdx.Close",
750 ErrorKind::Protocol { .. } => "memdx.Protocol",
751 ErrorKind::Cancelled(_) => "memdx.Cancelled",
752 ErrorKind::ConnectionFailed { .. } => "memdx.ConnectionFailed",
753 ErrorKind::Io => "memdx.Io",
754 ErrorKind::InvalidArgument { .. } => "memdx.InvalidArgument",
755 ErrorKind::Decompression => "memdx.Decompression",
756 ErrorKind::Message(_) => "memdx._OTHER",
757 }
758 }
759}
760
761impl MetricsName for ServerErrorKind {
762 fn metrics_name(&self) -> &'static str {
763 match self {
764 ServerErrorKind::KeyNotFound => "memdx.KeyNotFound",
765 ServerErrorKind::KeyExists => "memdx.KeyExists",
766 ServerErrorKind::TooBig => "memdx.TooBig",
767 ServerErrorKind::NotStored => "memdx.NotStored",
768 ServerErrorKind::BadDelta => "memdx.BadDelta",
769 ServerErrorKind::NotMyVbucket => "memdx.NotMyVbucket",
770 ServerErrorKind::NoBucket => "memdx.NoBucket",
771 ServerErrorKind::Locked => "memdx.Locked",
772 ServerErrorKind::NotLocked => "memdx.NotLocked",
773 ServerErrorKind::Auth { .. } => "memdx.Auth",
774 ServerErrorKind::RangeError => "memdx.RangeError",
775 ServerErrorKind::Access => "memdx.Access",
776 ServerErrorKind::RateLimitedNetworkIngress => "memdx.RateLimitedNetworkIngress",
777 ServerErrorKind::RateLimitedNetworkEgress => "memdx.RateLimitedNetworkEgress",
778 ServerErrorKind::RateLimitedMaxConnections => "memdx.RateLimitedMaxConnections",
779 ServerErrorKind::RateLimitedMaxCommands => "memdx.RateLimitedMaxCommands",
780 ServerErrorKind::RateLimitedScopeSizeLimitExceeded => {
781 "memdx.RateLimitedScopeSizeLimitExceeded"
782 }
783 ServerErrorKind::UnknownCommand => "memdx.UnknownCommand",
784 ServerErrorKind::NotSupported => "memdx.NotSupported",
785 ServerErrorKind::InternalError => "memdx.InternalError",
786 ServerErrorKind::Busy => "memdx.Busy",
787 ServerErrorKind::TmpFail => "memdx.TmpFail",
788 ServerErrorKind::UnknownCollectionID => "memdx.UnknownCollectionID",
789 ServerErrorKind::UnknownScopeName => "memdx.UnknownScopeName",
790 ServerErrorKind::UnknownCollectionName => "memdx.UnknownCollectionName",
791 ServerErrorKind::DurabilityInvalid => "memdx.DurabilityInvalid",
792 ServerErrorKind::DurabilityImpossible => "memdx.DurabilityImpossible",
793 ServerErrorKind::SyncWriteInProgress => "memdx.SyncWriteInProgress",
794 ServerErrorKind::SyncWriteAmbiguous => "memdx.SyncWriteAmbiguous",
795 ServerErrorKind::SyncWriteRecommitInProgress => "memdx.SyncWriteRecommitInProgress",
796 ServerErrorKind::RangeScanCancelled => "memdx.RangeScanCancelled",
797 ServerErrorKind::RangeScanVBUUIDNotEqual => "memdx.RangeScanVBUUIDNotEqual",
798 ServerErrorKind::InvalidArgs => "memdx.InvalidArgs",
799 ServerErrorKind::AuthStale => "memdx.AuthStale",
800 ServerErrorKind::ConfigNotSet => "memdx.ConfigNotSet",
801 ServerErrorKind::UnknownBucketName => "memdx.UnknownBucketName",
802 ServerErrorKind::CasMismatch => "memdx.CasMismatch",
803 ServerErrorKind::Subdoc { error } => error.kind().metrics_name(),
804 ServerErrorKind::UnknownStatus { .. } => "memdx._OTHER",
805 }
806 }
807}
808
809impl MetricsName for SubdocErrorKind {
810 fn metrics_name(&self) -> &'static str {
811 match self {
812 SubdocErrorKind::PathNotFound => "memdx.subdoc.PathNotFound",
813 SubdocErrorKind::PathMismatch => "memdx.subdoc.PathMismatch",
814 SubdocErrorKind::PathInvalid => "memdx.subdoc.PathInvalid",
815 SubdocErrorKind::PathTooBig => "memdx.subdoc.PathTooBig",
816 SubdocErrorKind::DocTooDeep => "memdx.subdoc.DocTooDeep",
817 SubdocErrorKind::CantInsert => "memdx.subdoc.CantInsert",
818 SubdocErrorKind::NotJSON => "memdx.subdoc.NotJSON",
819 SubdocErrorKind::BadRange => "memdx.subdoc.BadRange",
820 SubdocErrorKind::BadDelta => "memdx.subdoc.BadDelta",
821 SubdocErrorKind::PathExists => "memdx.subdoc.PathExists",
822 SubdocErrorKind::ValueTooDeep => "memdx.subdoc.ValueTooDeep",
823 SubdocErrorKind::InvalidCombo => "memdx.subdoc.InvalidCombo",
824 SubdocErrorKind::XattrInvalidFlagCombo => "memdx.subdoc.XattrInvalidFlagCombo",
825 SubdocErrorKind::XattrInvalidKeyCombo => "memdx.subdoc.XattrInvalidKeyCombo",
826 SubdocErrorKind::XattrUnknownMacro => "memdx.subdoc.XattrUnknownMacro",
827 SubdocErrorKind::XattrUnknownVAttr => "memdx.subdoc.XattrUnknownVAttr",
828 SubdocErrorKind::XattrCannotModifyVAttr => "memdx.subdoc.XattrCannotModifyVAttr",
829 SubdocErrorKind::InvalidXattrOrder => "memdx.subdoc.InvalidXattrOrder",
830 SubdocErrorKind::XattrUnknownVattrMacro => "memdx.subdoc.XattrUnknownVattrMacro",
831 SubdocErrorKind::CanOnlyReviveDeletedDocuments => {
832 "memdx.subdoc.CanOnlyReviveDeletedDocuments"
833 }
834 SubdocErrorKind::DeletedDocumentCantHaveValue => {
835 "memdx.subdoc.DeletedDocumentCantHaveValue"
836 }
837 SubdocErrorKind::UnknownStatus { .. } => "memdx.subdoc._OTHER",
838 }
839 }
840}