আপনি যদি কখনো রুবির এক্সেপশন হায়ারার্কি দেখেন, তবে আপনি কিছু অদ্ভুত জিনিস লক্ষ্য করতে পারেন। নরমাল এক্সেপশনগুলো যেমন RuntimeError এবং NoMethodError এর পাশাপাশি, এতে একটি অদ্ভুত রেফারেন্স রয়েছে Errno::*।
Exception StandardError ... SystemCallError Errno::* ... আপনি যদি কখনো ডিস্ক ফুল থাকা অবস্থায় ডিস্কে লিখতে চেয়েছেন, অথবা একটি ফেইলিং নেটওয়ার্কের ওপর API কল করতে চেয়েছেন, তবে আপনি সম্ভবত এই টাইপের এরর একশনে দেখেছেন। আপনি এখনই একটা ট্রিগার করতে পারেন একটি ফাইল ওপেন করার চেষ্টা করে যেটি এক্সিস্ট করে না।
irb> File.open("badfilename.txt") Errno::ENOENT: No such file or directory @ rb_sysopen - badfilename.txt from (irb):9:in `initialize' from (irb):9:in `open' from (irb):9 from /Users/snhorne/.rbenv/versions/2.1.0/bin/irb:11:in `<main>' কিন্তু Errno এক্সেপশনগুলো আসলে কী? এবং কেন এগুলো অন্যান্য এক্সেপশন থেকে আলাদা ভাবে ট리트 করা হয়?
রুবিকে OS-এর সাথে অ্যাডাপ্ট করা
Errno এক্সেপশনগুলো মূলত একটি অ্যাডাপ্টার। এগুলো অপারেটিং সিস্টেম এররকে রুবির এক্সেপশন সিস্টেমের সাথে কানেক্ট করে। অপারেটিং সিস্টেম এরর হ্যান্ডেল করে রুবির থেকে আলাদা ভাবে, তাই আপনাকে অবশ্যই একটি অ্যাডাপ্টার থাকতে হবে।
রুবিতে, এররগুলো সাধারণত এক্সেপশন হিসেবে রিপোর্ট হয়। কিন্তু অপারেটিং সিস্টেম এররগুলো সাধারণত শুধু ইন্টিজার। তাই রুবি প্রতিটি সম্ভাব্য OS এররের জন্য একটি এক্সেপশন ক্লাস ডিফাইন করে। তারপর এই সকল এক্সেপশনকে একটি মডিউল chiamato Errno-তে রাখে।
আমরা IRB ব্যবহার করে এই মডিউলের সকল এক্সেপশন দেখতে পারি। এবং বয়, কতগুলো!
irb> Errno.constants => [:NOERROR, :EPERM, :ENOENT, :ESRCH, :EINTR, :EIO, :ENXIO, :E2BIG, :ENOEXEC, :EBADF, :ECHILD, :EAGAIN, :ENOMEM, :EACCES, :EFAULT, :ENOTBLK, :EBUSY, :EEXIST, :EXDEV, :ENODEV, :ENOTDIR, :EISDIR, :EINVAL, :ENFILE, :EMFILE, :ENOTTY, :ETXTBSY, :EFBIG, :ENOSPC, :ESPIPE, :EROFS, :EMLINK, :EPIPE, :EDOM, :ERANGE, :EDEADLK, :ENAMETOOLONG, :ENOLCK, :ENOSYS, :ENOTEMPTY, :ELOOP, :EWOULDBLOCK, :ENOMSG, :EIDRM, :ECHRNG, :EL2NSYNC, :EL3HLT, :EL3RST, :ELNRNG, :EUNATCH, :ENOCSI, :EL2HLT, :EBADE, :EBADR, :EXFULL, :ENOANO, :EBADRQC, :EBADSLT, :EDEADLOCK, :EBFONT, :ENOSTR, :ENODATA, :ETIME, :ENOSR, :ENONET, :ENOPKG, :EREMOTE, :ENOLINK, :EADV, :ESRMNT, :ECOMM, :EPROTO, :EMULTIHOP, :EDOTDOT, :EBADMSG, :EOVERFLOW, :ENOTUNIQ, :EBADFD, :EREMCHG, :ELIBACC, :ELIBBAD, :ELIBSCN, :ELIBMAX, :ELIBEXEC, :EILSEQ, :ERESTART, :ESTRPIPE, :EUSERS, :ENOTSOCK, :EDESTADDRREQ, :EMSGSIZE, :EPROTOTYPE, :ENOPROTOOPT, :EPROTONOSUPPORT, :ESOCKTNOSUPPORT, :EOPNOTSUPP, :EPFNOSUPPORT, :EAFNOSUPPORT, :EADDRINUSE, :EADDRNOTAVAIL, :ENETDOWN, :ENETUNREACH, :ENETRESET, :ECONNABORTED, :ECONNRESET, :ENOBUFS, :EISCONN, :ENOTCONN, :ESHUTDOWN, :ETOOMANYREFS, :ETIMEDOUT, :ECONNREFUSED, :EHOSTDOWN, :EHOSTUNREACH, :EALREADY, :EINPROGRESS, :ESTALE, :EUCLEAN, :ENOTNAM, :ENAVAIL, :EISNAM, :EREMOTEIO, :EDQUOT, :ECANCELED, :EKEYEXPIRED, :EKEYREJECTED, :EKEYREVOKED, :EMEDIUMTYPE, :ENOKEY, :ENOMEDIUM, :ENOTRECOVERABLE, :EOWNERDEAD, :ERFKILL, :EAUTH, :EBADRPC, :EDOOFUS, :EFTYPE, :ENEEDAUTH, :ENOATTR, :ENOTSUP, :EPROCLIM, :EPROCUNAVAIL, :EPROGMISMATCH, :EPROGUNAVAIL, :ERPCMISMATCH, :EIPSEC] কিন্তু এগুলো এত ক্রিপ্টিকভাবে কেন নামকরণ করা হয়েছে? মানে, আমি কীভাবে অনুমান করব যে ENOINT মানে "File not found"?
...এটার আসলে একটি খুব সিম্পল উত্তর রয়েছে।
libc থেকে হোলসেইল কপি করা
Errno মডিউলটি প্রথম বানائতেছেন libc-র এরর নামগুলো সরাসরি কপি করেছেন। তাই ENOINT, C-এ, একটি ম্যাক্রোর নাম যেটি সেই ইন্টিজার এরর কোড ধারণ করে যা OS রিটার্ন করে যখন সেটি একটি ফাইল খুঁজে পায় না।
তাহলে, প্রতিটি কী করবে সেটি বুঝতে трিকটি হলো C স্ট্যান্ডার্ড লাইব্রেরির ডকুমেন্টেশন দেখা। আপনি এখানে একটি বড় লিস্ট পাবেন। আমি নিচে কিছু মোর রিলেভেন্টগুলো এক্সসার্প্ট করলাম:
| EPERM | Operation not permitted; আপনি ফাইলটি এক্সেস করতে পারবেন না যদি না আপনার পারমিশন থাকে। |
| ENOENT | File or directory not found. |
| EIO | Input/output error; সাধারণত ফিজিক্যাল রিড বা রাইট এররের জন্য ব্যবহৃত হয়। |
| EBADF | Bad file descriptor. আপনি এই এরর পাবেন যদি আপনি একটি ফাইলে রাইট করার চেষ্টা করেন যেটি আপনি শুধু রিডিংয়ের জন্য ওপেন করলেন। |
| ECHILD | আপনি একটি চাইল্ড প্রসেস ম্যানিপুলেট করার চেষ্টা করলেন, কিন্তু কোনো চাইল্ড প্রসেস নেই। |
| ENOMEM | আপনার RAM ফুল, আর ভার্চুয়াল মেমোরি অ্যালোকেট করতে পারছেন না। |
| EACCES | Permission denied; ফাইল পারমিশন চেষ্টা করা অপারেশন অনুমতি দেয় না। |
| ENOTBLK | আপনি একটি অর্ডিনারি ফাইলকে ডিভাইস হিসেবে মাউন্ট করার চেষ্টা করলেন, যেমন HDD। |
| EBUSY | Resource busy; একটি সিস্টেম রিসোর্স যা শেয়ার করা যাবে না সেটি ইতিমধ্যে ইন ইউজ। উদাহরণস্বরূপ, যদি আপনি একটি ফাইল ডিলিট করার চেষ্টা করেন যা একটি করেন্টলি মাউন্টেড ফাইলসিস্টেমের রুট, তবে আপনি এই এরর পাবেন। |
| EEXIST | File exists; একটি এক্সিস্টিং ফাইল স্পেসিফাই করা হয়েছে এমন কনটেক্সটে যেখানে শুধু একটি নতুন ফাইল স্পেসিফাই করা যাবে। |
| ENOTDIR | একটি ফাইল যা ডিরেক্টরি নয় সেটি স্পেসিফাই করা হয়েছে যখন একটি ডিরেক্টরি রিকোয়ায়ারড। |
| EISDIR | File is a directory; আপনি একটি ডিরেক্টরি ওপেন করতে পারবেন না রাইটিংয়ের জন্য, বা সেটিতে হার্ড লিঙ্ক তৈরি বা রিমুভ করতে পারবেন না। |
| EINVAL | Invalid argument। এটি লাইব্রেরি ফাংশনে ভুল আর্গুমেন্ট পাস করার বিভিন্ন ধরনের সমস্যা ইন্ডিকেট করতে ব্যবহৃত হয়। |
| EMFILE | কারেন্ট প্রসেসে খুব বেশি ফাইল ওপেন আছে এবং আর কোনো ফাইল ওপেন করতে পারছে না। ডুপ্লিকেট ডেসক্রিপ্টরও এই লিমিটের দিকে কাউন্ট হয়। |
| EFBIG | File too big; একটি ফাইলের সাইজ সিস্টেম tarafından অ্যালাউড সাইজের চেয়ে বড় হয়ে যাবে। |
| ENOSPC | No space left on device; ডিস্ক ফুল থাকায় ফাইলে রাইট অপারেশন ফেল করেছে। |
| ESPIPE | Invalid seek operation (যেমন পাইপের ওপর)। |
| EROFS | একটি রিড-অনলি ফাইল সিস্টেমে কিছু মডিফাই করার চেষ্টা করা হয়েছে। |
| EPIPE | Broken pipe; পাইপের অন্য দিক থেকে পড়তে কোনো প্রসেস নেই। |
| ENOTSOCK | একটি ফাইল যা সকেট নয় সেটি স্পেসিফাই করা হয়েছে যখন একটি সকেট রিকোয়ায়ারড। |
| ENETUNREACH | একটি সকেট অপারেশন ফেল করলো কারণ রিমোট হোস্ট সম্বলিত সাবনেটটি অনুপ্রাপ্য ছিল। |
| ENETRESET | একটি নেটওয়ার্ক কানেকশন রিসেট হয়েছে কারণ রিমোট হোস্ট ক্র্যাশ করল। |
| ECONNABORTED | একটি নেটওয়ার্ক কানেকশন লোকালি অ্যাবোর্ট করা হয়েছে। |
| ECONNRESET | একটি নেটওয়ার্ক কানেকশন লোকাল হোস্টের কন্ট্রোল বাহিরের কারণে বন্ধ হয়েছে, যেমন রিমোট মেশিন রিবুট বা অনরিকভারেবল প্রোটোকল ভায়লেশন। |
| ENOBUFS | কার্নেলের I/O অপারেশনের জন্য বাফারগুলো সকল ইন ইউজ। GNU-এ, এই এরর সবসময় ENOMEM-এর সিনোনিমাস; আপনি নেটওয়ার্ক অপারেশন থেকে যেকোনো একটি পেতে পারেন। |
| EISCONN | আপনি একটি সকেট কানেক্ট করার চেষ্টা করলেন যা ইতিমধ্যে কানেক্টেড। Connecting দেখুন। |
| ENOTCONN | সকেটটি যেকোনো কিছুর সাথে কানেক্টেড নয়। আপনি এই এরর পাবেন যখন আপনি একটি সকেটের ওপর ডেটা ট্রান্সমিট করার চেষ্টা করছেন, ডেসটিনেশন স্পেসিফাই করা ছাড়া। |
| EDESTADDRREQ | সকেটের জন্য কোনো ডিফল্ট ডেসটিনেশন অ্যাড্রেস সেট নেই। আপনি এই এরর পাবেন যখন আপনি একটি কানেকশনলেস সকেটের ওপর ডেটা ট্রান্সমিট করার চেষ্টা করছেন, connect দিয়ে ডেসটিনেশন স্পেসিফাই করা ছাড়া। |
| ESHUTDOWN | সকেটটি ইতিমধ্যে শাট ডাউন করা হয়েছে। |
| ETIMEDOUT | একটি স্পেসিফাইড টাইমআউটসহ সকেট অপারেশন টাইমআউট পিরিয়ডের দুরান কোনো রেসপন্স পেলো না। |
| ECONNREFUSED | একটি রিমোট হোস্ট নেটওয়ার্ক কানেকশন অনুমতি দিতে অস্বীকার করল (সাধারণত কারণ সেটি রিকোয়েস্টেড সার্ভিস রান করছে না)। |
| EHOSTDOWN | একটি রিকোয়েস্টেড নেটওয়ার্ক কানেকশনের জন্য রিমোট হোস্ট ডাউন। |
| EHOSTUNREACH | একটি রিকোয়েস্টেড নেটওয়ার্ক কানেকশনের জন্য রিমোট হোস্ট অনুপ্রাপ্য। |
| ENOTEMPTY | Directory not empty, যেখানে একটি খালি ডিরেক্টরি এক্সপেক্টেড। সাধারণত, এই এরর ঘটে যখন আপনি একটি ডিরেক্টরি ডিলিট করার চেষ্টা করেন। |
| EPROCLIM | এটি মানে পার-ইউজার লিমিট নতুন প্রসেসের ওপর অতিক্রম করবে একটি অ্যাটেম্পটেড ফর্ক দ্বারা। Limits on Resources দেখুন, RLIMIT_NPROC লিমিটের ডিটেইলসের জন্য। |