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