@@ -485,6 +485,334 @@ enum ErrorCode : uint16_t {
485485 OTHER = 65535 ,
486486};
487487
488+ namespace exception {
489+ class Base {
490+ public:
491+ ErrorCode code;
492+ std::string message;
493+ std::list<std::string> sources;
494+
495+ private:
496+ const char * _class_name;
497+
498+ public:
499+ Base (ErrorCode code, const char * class_name, std::string message, std::list<std::string> sources) noexcept :
500+ code (code),
501+ _class_name (class_name),
502+ message (std::move(message)),
503+ sources (std::move(sources))
504+ {}
505+
506+ std::string to_string () noexcept {
507+ std::stringstream ss;
508+ ss << _class_name;
509+ // TODO: message and sources
510+ return ss.str ();
511+ }
512+ };
513+
514+ /* *
515+ * Insuficient permission to perform the intended operation
516+ */
517+ struct PermissionDenied : public Base {
518+ PermissionDenied (std::string message = {}, std::list<std::string> sources = {}):
519+ Base (ErrorCode::PERMISSION_DENIED, " PermissionDenied" , std::move(message), std::move(sources)) {}
520+ };
521+
522+ /* *
523+ * Invalid input parameter
524+ */
525+ struct InvalidInput : public Base {
526+ InvalidInput (std::string message = {}, std::list<std::string> sources = {}):
527+ Base (ErrorCode::INVALID_INPUT, " InvalidInput" , std::move(message), std::move(sources)) {}
528+ };
529+
530+ /* *
531+ * Invalid data (e.g., malformed incoming message, config file, etc...)
532+ */
533+ struct InvalidData : public Base {
534+ InvalidData (std::string message = {}, std::list<std::string> sources = {}):
535+ Base (ErrorCode::INVALID_DATA, " InvalidData" , std::move(message), std::move(sources)) {}
536+ };
537+
538+ /* *
539+ * Entry already exists
540+ */
541+ struct AlreadyExists : public Base {
542+ AlreadyExists (std::string message = {}, std::list<std::string> sources = {}):
543+ Base (ErrorCode::ALREADY_EXISTS, " AlreadyExists" , std::move(message), std::move(sources)) {}
544+ };
545+
546+ /* *
547+ * Entry not found
548+ */
549+ struct NotFound : public Base {
550+ NotFound (std::string message = {}, std::list<std::string> sources = {}):
551+ Base (ErrorCode::NOT_FOUND, " NotFound" , std::move(message), std::move(sources)) {}
552+ };
553+
554+ /* *
555+ * Multiple matching entries found
556+ */
557+ struct Ambiguous : public Base {
558+ Ambiguous (std::string message = {}, std::list<std::string> sources = {}):
559+ Base (ErrorCode::AMBIGUOUS, " Ambiguous" , std::move(message), std::move(sources)) {}
560+ };
561+
562+ /* *
563+ * The indended operation is not supported
564+ */
565+ struct Unsupported : public Base {
566+ Unsupported (std::string message = {}, std::list<std::string> sources = {}):
567+ Base (ErrorCode::UNSUPPORTED, " Unsupported" , std::move(message), std::move(sources)) {}
568+ };
569+
570+ /* *
571+ * The operation was interrupted
572+ */
573+ struct Interrupted : public Base {
574+ Interrupted (std::string message = {}, std::list<std::string> sources = {}):
575+ Base (ErrorCode::INTERRUPTED, " Interrupted" , std::move(message), std::move(sources)) {}
576+ };
577+
578+ /* *
579+ * Failed to establish connection to the server
580+ */
581+ struct ConnectionRefused : public Base {
582+ ConnectionRefused (std::string message = {}, std::list<std::string> sources = {}):
583+ Base (ErrorCode::CONNECTION_REFUSED, " ConnectionRefused" , std::move(message), std::move(sources)) {}
584+ };
585+
586+ /* *
587+ * Connection aborted by the server
588+ */
589+ struct ConnectionAborted : public Base {
590+ ConnectionAborted (std::string message = {}, std::list<std::string> sources = {}):
591+ Base (ErrorCode::CONNECTION_ABORTED, " ConnectionAborted" , std::move(message), std::move(sources)) {}
592+ };
593+
594+ /* *
595+ * Failed to send or receive message
596+ */
597+ struct TransportError : public Base {
598+ TransportError (std::string message = {}, std::list<std::string> sources = {}):
599+ Base (ErrorCode::TRANSPORT_ERROR, " TransportError" , std::move(message), std::move(sources)) {}
600+ };
601+
602+ /* *
603+ * Listener failed to bind to the specified address
604+ */
605+ struct ListenerBindError : public Base {
606+ ListenerBindError (std::string message = {}, std::list<std::string> sources = {}):
607+ Base (ErrorCode::LISTENER_BIND_ERROR, " ListenerBindError" , std::move(message), std::move(sources)) {}
608+ };
609+
610+ /* *
611+ * Listener failed to accept client connection
612+ */
613+ struct ListenerAcceptError : public Base {
614+ ListenerAcceptError (std::string message = {}, std::list<std::string> sources = {}):
615+ Base (ErrorCode::LISTENER_ACCEPT_ERROR, " ListenerAcceptError" , std::move(message), std::move(sources)) {}
616+ };
617+
618+ /* *
619+ * Operation on the internal repository store failed
620+ */
621+ struct StoreError : public Base {
622+ StoreError (std::string message = {}, std::list<std::string> sources = {}):
623+ Base (ErrorCode::STORE_ERROR, " StoreError" , std::move(message), std::move(sources)) {}
624+ };
625+
626+ /* *
627+ * Entry was expected to not be a directory but it is
628+ */
629+ struct IsDirectory : public Base {
630+ IsDirectory (std::string message = {}, std::list<std::string> sources = {}):
631+ Base (ErrorCode::IS_DIRECTORY, " IsDirectory" , std::move(message), std::move(sources)) {}
632+ };
633+
634+ /* *
635+ * Entry was expected to be a directory but it isn't
636+ */
637+ struct NotDirectory : public Base {
638+ NotDirectory (std::string message = {}, std::list<std::string> sources = {}):
639+ Base (ErrorCode::NOT_DIRECTORY, " NotDirectory" , std::move(message), std::move(sources)) {}
640+ };
641+
642+ /* *
643+ * Directory was expected to be empty but it isn't
644+ */
645+ struct DirectoryNotEmpty : public Base {
646+ DirectoryNotEmpty (std::string message = {}, std::list<std::string> sources = {}):
647+ Base (ErrorCode::DIRECTORY_NOT_EMPTY, " DirectoryNotEmpty" , std::move(message), std::move(sources)) {}
648+ };
649+
650+ /* *
651+ * File or directory is busy
652+ */
653+ struct ResourceBusy : public Base {
654+ ResourceBusy (std::string message = {}, std::list<std::string> sources = {}):
655+ Base (ErrorCode::RESOURCE_BUSY, " ResourceBusy" , std::move(message), std::move(sources)) {}
656+ };
657+
658+ /* *
659+ * Failed to initialize runtime
660+ */
661+ struct RuntimeInitializeError : public Base {
662+ RuntimeInitializeError (std::string message = {}, std::list<std::string> sources = {}):
663+ Base (ErrorCode::RUNTIME_INITIALIZE_ERROR, " RuntimeInitializeError" , std::move(message), std::move(sources)) {}
664+ };
665+
666+ /* *
667+ * Failed to read from or write into the config file
668+ */
669+ struct ConfigError : public Base {
670+ ConfigError (std::string message = {}, std::list<std::string> sources = {}):
671+ Base (ErrorCode::CONFIG_ERROR, " ConfigError" , std::move(message), std::move(sources)) {}
672+ };
673+
674+ /* *
675+ * TLS certificated not found
676+ */
677+ struct TlsCertificatesNotFound : public Base {
678+ TlsCertificatesNotFound (std::string message = {}, std::list<std::string> sources = {}):
679+ Base (ErrorCode::TLS_CERTIFICATES_NOT_FOUND, " TlsCertificatesNotFound" , std::move(message), std::move(sources)) {}
680+ };
681+
682+ /* *
683+ * TLS certificates failed to load
684+ */
685+ struct TlsCertificatesInvalid : public Base {
686+ TlsCertificatesInvalid (std::string message = {}, std::list<std::string> sources = {}):
687+ Base (ErrorCode::TLS_CERTIFICATES_INVALID, " TlsCertificatesInvalid" , std::move(message), std::move(sources)) {}
688+ };
689+
690+ /* *
691+ * TLS keys not found
692+ */
693+ struct TlsKeysNotFound : public Base {
694+ TlsKeysNotFound (std::string message = {}, std::list<std::string> sources = {}):
695+ Base (ErrorCode::TLS_KEYS_NOT_FOUND, " TlsKeysNotFound" , std::move(message), std::move(sources)) {}
696+ };
697+
698+ /* *
699+ * Failed to create TLS config
700+ */
701+ struct TlsConfigError : public Base {
702+ TlsConfigError (std::string message = {}, std::list<std::string> sources = {}):
703+ Base (ErrorCode::TLS_CONFIG_ERROR, " TlsConfigError" , std::move(message), std::move(sources)) {}
704+ };
705+
706+ /* *
707+ * Failed to install virtual filesystem driver
708+ */
709+ struct VfsDriverInstallError : public Base {
710+ VfsDriverInstallError (std::string message = {}, std::list<std::string> sources = {}):
711+ Base (ErrorCode::VFS_DRIVER_INSTALL_ERROR, " VfsDriverInstallError" , std::move(message), std::move(sources)) {}
712+ };
713+
714+ /* *
715+ * Unspecified virtual filesystem error
716+ */
717+ struct VfsOtherError : public Base {
718+ VfsOtherError (std::string message = {}, std::list<std::string> sources = {}):
719+ Base (ErrorCode::VFS_OTHER_ERROR, " VfsOtherError" , std::move(message), std::move(sources)) {}
720+ };
721+
722+ /* *
723+ * Another instance of the service is already running
724+ */
725+ struct ServiceAlreadyRunning : public Base {
726+ ServiceAlreadyRunning (std::string message = {}, std::list<std::string> sources = {}):
727+ Base (ErrorCode::SERVICE_ALREADY_RUNNING, " ServiceAlreadyRunning" , std::move(message), std::move(sources)) {}
728+ };
729+
730+ /* *
731+ * Store directory is not specified
732+ */
733+ struct StoreDirUnspecified : public Base {
734+ StoreDirUnspecified (std::string message = {}, std::list<std::string> sources = {}):
735+ Base (ErrorCode::STORE_DIR_UNSPECIFIED, " StoreDirUnspecified" , std::move(message), std::move(sources)) {}
736+ };
737+
738+ /* *
739+ * Mount directory is not specified
740+ */
741+ struct MountDirUnspecified : public Base {
742+ MountDirUnspecified (std::string message = {}, std::list<std::string> sources = {}):
743+ Base (ErrorCode::MOUNT_DIR_UNSPECIFIED, " MountDirUnspecified" , std::move(message), std::move(sources)) {}
744+ };
745+
746+ static std::unique_ptr<Base> dispatch (
747+ ErrorCode code,
748+ std::string message = {},
749+ std::list<std::string> sources = {}
750+ ) {
751+ switch (code) {
752+ case ErrorCode::PERMISSION_DENIED:
753+ return std::make_unique<PermissionDenied>(std::move (message), std::move (sources));
754+ case ErrorCode::INVALID_INPUT:
755+ return std::make_unique<InvalidInput>(std::move (message), std::move (sources));
756+ case ErrorCode::INVALID_DATA:
757+ return std::make_unique<InvalidData>(std::move (message), std::move (sources));
758+ case ErrorCode::ALREADY_EXISTS:
759+ return std::make_unique<AlreadyExists>(std::move (message), std::move (sources));
760+ case ErrorCode::NOT_FOUND:
761+ return std::make_unique<NotFound>(std::move (message), std::move (sources));
762+ case ErrorCode::AMBIGUOUS:
763+ return std::make_unique<Ambiguous>(std::move (message), std::move (sources));
764+ case ErrorCode::UNSUPPORTED:
765+ return std::make_unique<Unsupported>(std::move (message), std::move (sources));
766+ case ErrorCode::INTERRUPTED:
767+ return std::make_unique<Interrupted>(std::move (message), std::move (sources));
768+ case ErrorCode::CONNECTION_REFUSED:
769+ return std::make_unique<ConnectionRefused>(std::move (message), std::move (sources));
770+ case ErrorCode::CONNECTION_ABORTED:
771+ return std::make_unique<ConnectionAborted>(std::move (message), std::move (sources));
772+ case ErrorCode::TRANSPORT_ERROR:
773+ return std::make_unique<TransportError>(std::move (message), std::move (sources));
774+ case ErrorCode::LISTENER_BIND_ERROR:
775+ return std::make_unique<ListenerBindError>(std::move (message), std::move (sources));
776+ case ErrorCode::LISTENER_ACCEPT_ERROR:
777+ return std::make_unique<ListenerAcceptError>(std::move (message), std::move (sources));
778+ case ErrorCode::STORE_ERROR:
779+ return std::make_unique<StoreError>(std::move (message), std::move (sources));
780+ case ErrorCode::IS_DIRECTORY:
781+ return std::make_unique<IsDirectory>(std::move (message), std::move (sources));
782+ case ErrorCode::NOT_DIRECTORY:
783+ return std::make_unique<NotDirectory>(std::move (message), std::move (sources));
784+ case ErrorCode::DIRECTORY_NOT_EMPTY:
785+ return std::make_unique<DirectoryNotEmpty>(std::move (message), std::move (sources));
786+ case ErrorCode::RESOURCE_BUSY:
787+ return std::make_unique<ResourceBusy>(std::move (message), std::move (sources));
788+ case ErrorCode::RUNTIME_INITIALIZE_ERROR:
789+ return std::make_unique<RuntimeInitializeError>(std::move (message), std::move (sources));
790+ case ErrorCode::CONFIG_ERROR:
791+ return std::make_unique<ConfigError>(std::move (message), std::move (sources));
792+ case ErrorCode::TLS_CERTIFICATES_NOT_FOUND:
793+ return std::make_unique<TlsCertificatesNotFound>(std::move (message), std::move (sources));
794+ case ErrorCode::TLS_CERTIFICATES_INVALID:
795+ return std::make_unique<TlsCertificatesInvalid>(std::move (message), std::move (sources));
796+ case ErrorCode::TLS_KEYS_NOT_FOUND:
797+ return std::make_unique<TlsKeysNotFound>(std::move (message), std::move (sources));
798+ case ErrorCode::TLS_CONFIG_ERROR:
799+ return std::make_unique<TlsConfigError>(std::move (message), std::move (sources));
800+ case ErrorCode::VFS_DRIVER_INSTALL_ERROR:
801+ return std::make_unique<VfsDriverInstallError>(std::move (message), std::move (sources));
802+ case ErrorCode::VFS_OTHER_ERROR:
803+ return std::make_unique<VfsOtherError>(std::move (message), std::move (sources));
804+ case ErrorCode::SERVICE_ALREADY_RUNNING:
805+ return std::make_unique<ServiceAlreadyRunning>(std::move (message), std::move (sources));
806+ case ErrorCode::STORE_DIR_UNSPECIFIED:
807+ return std::make_unique<StoreDirUnspecified>(std::move (message), std::move (sources));
808+ case ErrorCode::MOUNT_DIR_UNSPECIFIED:
809+ return std::make_unique<MountDirUnspecified>(std::move (message), std::move (sources));
810+ default :
811+ return std::make_unique<Base>(code, " Unknown" , std::move (message), std::move (sources));
812+ }
813+ }
814+ } // namespace exception
815+
488816
489817enum LogLevel : uint8_t {
490818 ERROR = 1 ,
0 commit comments