module Knot class Error < ::Exception attr_reader :Errno attr_reader :Key attr_reader :Errstr end end module Knot::Errors @num2exc = {} @key2exc = {} @err2exc = {} class << self attr_reader :num2exc, :key2exc, :err2exc def array_arguments_with_typecheck *args l = args.length lambda do |a| l == a.length and args.zip(a).all? {|t,v| t === v } end end end def method_missing key self[key] end def [] key_or_errno case key_or_errno when Integer @num2exc[key_or_errno] when Exception key_or_errno when Symbol @key2exc[key_or_errno] else raise ArgumentError, "Invalid type. Expect Integer/Knot::Error/Symbol" end end i = 0 [ [:EOK, 0, "OK"], # Directly mapped error codes. [:ENOMEM, -Errno::ENOMEM::Errno, "not enough memory" ], [:EINVAL, -Errno::EINVAL::Errno, "invalid parameter" ], [:ENOTSUP, -Errno::ENOTSUP::Errno, "operation not supported" ], [:EBUSY, -Errno::EBUSY::Errno, "requested resource is busy" ], [:EAGAIN, -Errno::EAGAIN::Errno, "OS lacked necessary resources" ], [:EACCES, -Errno::EACCES::Errno, "operation not permitted" ], [:ECONNREFUSED, -Errno::ECONNREFUSED::Errno, "connection refused" ], [:EISCONN, -Errno::EISCONN::Errno, "already connected" ], [:EADDRINUSE, -Errno::EADDRINUSE::Errno, "address already in use" ], [:ENOENT, -Errno::ENOENT::Errno, "not exists" ], [:EEXIST, -Errno::EEXIST::Errno, "already exists" ], [:ERANGE, -Errno::ERANGE::Errno, "value is out of range" ], [:EADDRNOTAVAIL, -Errno::EADDRNOTAVAIL::Errno, "address is not available" ], # General errors. [:ERROR, -1000, "failed"], [:EPARSEFAIL, "parser failed"], [:ESEMCHECK, "semantic check"], [:EUPTODATE, "zone is up-to-date"], [:EFEWDATA, "not enough data to parse"], [:ESPACE, "not enough space provided"], [:EMALF, "malformed data"], [:ENSEC3PAR, "missing or wrong NSEC3PARAM record"], [:ENSEC3CHAIN, "missing or wrong NSEC3 chain in the zone"], [:EOUTOFZONE, "name does not belong to the zone"], [:EZONEINVAL, "invalid zone file"], [:ENOZONE, "no such zone found"], [:ENONODE, "no such node in zone found"], [:ENORECORD, "no such record in zone found"], [:EISRECORD, "such record already exists in zone"], [:ENOMASTER, "no usable master"], [:EPREREQ, "UPDATE prerequisity not met"], [:ETTL, "TTL mismatch"], [:ENOXFR, "transfer was not sent"], [:EDENIED, "not allowed"], [:ECONN, "connection reset"], [:ETIMEOUT, "connection timeout"], [:ENODIFF, "cannot create zone diff"], [:ENOTSIG, "expected a TSIG or SIG(0)"], [:ELIMIT, "exceeded response rate limit"], [:EZONESIZE, "zone size exceeded"], [:EOF, "end of file"], [:ESYSTEM, "system error"], [:EFILE, "file error"], [:ESOAINVAL, "SOA mismatch"], [:ETRAIL, "trailing data"], [:EPROCESSING, "processing error"], # Control states. [:CTL_ESTOP, "stopping server"], # Network errors. [:NET_EADDR, "bad address or host name"], [:NET_ESOCKET, "can't create socket"], [:NET_ECONNECT, "can't connect"], [:NET_ESEND, "can't send data"], [:NET_ERECV, "can't receive data"], [:NET_ETIMEOUT, "network timeout"], # Encoding errors. [:BASE64_ESIZE, "invalid base64 string length"], [:BASE64_ECHAR, "invalid base64 character"], [:BASE32HEX_ESIZE, "invalid base32hex string length"], [:BASE32HEX_ECHAR, "invalid base32hex character"], # TSIG errors. [:KNOT_TSIG_EBADSIG, "failed to verify TSIG"], [:KNOT_TSIG_EBADKEY, "TSIG key not recognized or invalid"], [:KNOT_TSIG_EBADTIME, "TSIG out of time window"], [:KNOT_TSIG_EBADTRUNC, "TSIG bad truncation"], # DNSSEC errors. [:DNSSEC_ENOKEY, "no keys for signing"], [:DNSSEC_EMISSINGKEYTYPE, "missing active KSK or ZSK"], # Yparser errors. [:YP_ECHAR_TAB, "tabulator character is not allowed"], [:YP_EINVAL_ITEM, "invalid item"], [:YP_EINVAL_ID, "invalid identifier"], [:YP_EINVAL_DATA, "invalid value"], [:YP_EINVAL_INDENT, "invalid indentation"], [:YP_ENOTSUP_DATA, "value not supported"], [:YP_ENOTSUP_ID, "identifier not supported"], [:YP_ENODATA, "missing value"], [:YP_ENOID, "missing identifier"], # Configuration errors. [:CONF_ENOTINIT, "config DB not initialized"], [:CONF_EVERSION, "invalid config DB version"], [:CONF_EREDEFINE, "duplicate identifier"], # Transaction errors. [:TXN_EEXISTS, "too many transactions"], [:TXN_ENOTEXISTS, "no active transaction"], # DNSSEC errors. [:INVALID_PUBLIC_KEY, "invalid public key"], [:INVALID_PRIVATE_KEY, "invalid private key"], [:INVALID_KEY_ALGORITHM, "invalid key algorithm"], [:INVALID_KEY_SIZE, "invalid key size"], [:INVALID_KEY_ID, "invalid key ID"], [:INVALID_KEY_NAME, "invalid key name"], [:NO_PUBLIC_KEY, "no public key"], [:NO_PRIVATE_KEY, "no private key"], ].each do |v| e = nil case v when array_arguments_with_typecheck( Symbol, String) v, e = v when array_arguments_with_typecheck( String, String) v, e = v v = v.to_sym when array_arguments_with_typecheck( Symbol, Integer, String) v, i, e = v when array_arguments_with_typecheck( String, Integer, String) v, i, e = v v = v.to_sym else raise ArgumentError, "[Symbol, String] | [Symbol, Int, String] expected, not #{v}" end cl = Class.new Exception cl.const_set :Key, v cl.const_set :Errno, i cl.const_set :Errstr, e const_set v, cl @num2exc[i] = @key2exc[v] = @err2exc[e] = cl i += 1 end end