module Eco module API # To identify api server errors class Error < StandardError class UnknownErrorClass < StandardError def initialize(msg = nil, klass:) msg ||= "Unkown api error class #{klass}" super(msg) end end @str_err = "api error on the server reply" @match = /.*/ #RxValidId = /[a-f0-9]{24}/ class Unclassified < Eco::API::Error @str_error = "Unclassified error message" @match = /.*/ end class InternalServerError < Eco::API::Error @str_err = "Internal Server Error" @match = /#{@str_err}/ end class UnknownPersonId < Eco::API::Error @str_err = "Unknown person id" @match = /Cannot find person with id (.*)/ end class ExternalIdTaken < Eco::API::Error @str_err = "external ID already taken" @match = /#{@str_err}/ end class EmailMissing < Eco::API::Error @str_err = "missing email for account creation" @match = /#{@str_err}/ end class EmailInvalid < Eco::API::Error @str_err = "Email is invalid" @match = /#{@str_err}/ end class EmailTaken < Eco::API::Error @str_err = "user email already taken" @str_err2 = "Email is already taken" @match = /(?:#{@str_err}|#{@str_err2})/ end class SupervisorNotFound < Eco::API::Error @str_err = "Supervisor not found" @match = /Supervisor (.*?) not found/ end class CyclicSupervisor < Eco::API::Error @str_err = "Supervisor is cyclic!" @match = /#{@str_err}/ end class SchemaNotFound < Eco::API::Error @str_err = "Schema not found" @match = /Schema (.*?) not found/ end class InvalidObjectId < Eco::API::Error @str_err = "Invalid ObjectId." @match = /'(.*?)' is an invalid ObjectId./ end class UnkownField < Eco::API::Error @str_err = "Unknown field." @match = /(.+?) is an unknown field/ class UnkownCoreField < UnkownField @str_err = "Unknown core field." @match = /(.+?) is an unknown field/ end class UnkownAccountField < UnkownField @str_err = "Unknown account field." @match = /account \> (.+?) is an unknown field/ end class UnkownDetailsField < UnkownField @str_err = "Unknown details field." @match = /details \> (.+?) is an unknown field/ end end class << self def descendants(direct: false) ObjectSpace.each_object(::Class).select do |klass| klass < self end.sort do |k1, k2| next -1 if k2 < k1 next 1 if k1 < k2 0 end.tap do |siblings| siblings.delete(Unclassified) if direct siblings.reject! do |si| siblings.any? {|s| si < s} end end end end def descendants?(direct: false) descendants(direct: direct).length > 0 end def err_match?(err_msg) err_msg =~ @match end def get_type(err_msg, first: true) type = nil descendants(direct: true).reverse.each do |klass| if klass.err_match?(err_msg) type = klass if klass.descendants?(direct: true) type = klass.get_type(err_msg, first: false) || type end end end return type unless first type || Unclassified end def known_err_class?(klass) descendants.push(self).include?(klass) end def validate_err_class(klass) raise UnknownErrorClass.new(klass: klass) unless known_err_class?(klass) end end attr_reader :msg, :err_msg, :session, :entry def initialize(msg = nil, err_msg:, session: nil, entry: nil) @msg = msg @err_msg = err_msg @session = session @entry = entry super(built_error) end def built_error str ||= msg end end end end require_relative 'error/handler' require_relative 'error/handlers'