Lua Academy · पाठ

संरचित त्रुटि ऑब्जेक्ट

प्रकार और संदर्भ बताने के लिए टेबल को त्रुटि ऑब्जेक्ट के रूप में भेजें।

पाठ 4, कुल 4 में से12 चरण

संरचित त्रुटि ऑब्जेक्ट, CoddyKit पर Lua Academy का एक निःशुल्क पाठ है। यह 4 में से 4वाँ पाठ है। इस अध्ययन पथ के 3 तक कोई भी पाठ पूरा पढ़ना निःशुल्क है — इसके बाद CoddyKit PRO हर पाठ अनलॉक करता है, साथ ही अंतर्निर्मित कोड संपादक और चौबीसों घंटे एआई शिक्षक के साथ व्यावहारिक अभ्यास भी उपलब्ध कराता है। यह Lua Academy सीखने के मार्ग का हिस्सा है और आपकी प्रगति वेब तथा CoddyKit ऐप पर सिंक होती रहती है। Lua Academy पाठ्यक्रम में कुल 4 पाठ शामिल हैं।

संरचित त्रुटियाँ क्यों?

साधारण स्ट्रिंग त्रुटियों को प्रोग्राम के माध्यम से संभालना कठिन होता है। संरचित त्रुटि ऑब्जेक्ट (टेबल) में प्रकार की जानकारी और संदर्भ डेटा होता है, तथा कॉल करने वाला उनकी जाँच करके कार्रवाई कर सकता है। इससे स्ट्रिंग का विश्लेषण किए बिना त्रुटि-आधारित वितरण संभव होता है।

-- Plain string: hard to handle programmatically
error("database error: connection refused")

-- Structured: type + data
error({
  type = "DatabaseError",
  code = "CONN_REFUSED",
  host = "localhost",
  port = 5432,
  message = "connection refused"
})

त्रुटि कंस्ट्रक्टर प्रतिरूप

प्रत्येक त्रुटि प्रकार के लिए एक त्रुटि फ़ैक्टरी फ़ंक्शन बनाएँ। फ़ैक्टरी सुसंगत फ़ील्ड वाली टेबल बनाती है: प्रकार, संदेश और कोई भी प्रासंगिक संदर्भ। __tostring मेटामेथड त्रुटि को अच्छी तरह प्रिंट करने योग्य बनाता है।

local ErrorMT = {__tostring = function(e)
  return string.format("[%s] %s", e.type, e.message)
end}

local function makeError(errType, msg, data)
  local e = {type=errType, message=msg}
  if data then for k,v in pairs(data) do e[k]=v end end
  return setmetatable(e, ErrorMT)
end

local E = {
  notFound = function(name) return makeError("NOT_FOUND","not found: "..name,{name=name}) end,
  badInput = function(msg,field) return makeError("BAD_INPUT",msg,{field=field}) end,
}

local ok, err = pcall(error, E.notFound("user:42"))
print(tostring(err))   -- [NOT_FOUND] not found: user:42

त्रुटि ऑब्जेक्ट का प्रकार जाँचना

त्रुटि पकड़ने के बाद जाँचें कि वह किसी ज्ञात प्रकार वाली टेबल है या नहीं। इससे स्ट्रिंग पैटर्न मिलान पर निर्भर हुए बिना त्रुटि प्रकार के आधार पर अलग-अलग पुनर्प्राप्ति रणनीतियाँ चुनी जा सकती हैं।

local function handleRequest(fn)
  local ok, err = pcall(fn)
  if ok then return true end
  if type(err) == "table" then
    if err.type == "NOT_FOUND" then
      print("404: " .. err.message)
    elseif err.type == "BAD_INPUT" then
      print("400: " .. err.message .. " (field: " .. (err.field or "?") .. ")")
    else
      print("500: unhandled error: " .. tostring(err))
    end
  else
    print("500: " .. tostring(err))
  end
  return false
end

त्रुटि पदानुक्रम

is_a फ़ील्ड की जाँच करके या मेटाटेबल का उपयोग करके त्रुटि पदानुक्रम का अनुकरण करें। बाल त्रुटि प्रकार मूल प्रकार के फ़ील्ड विरासत में लेते हैं और ऐसा कोड उन्हें मूल प्रकार की तरह संभाल सकता है जिसे विशेष विवरणों की आवश्यकता नहीं है।

local function isError(e, errType)
  if type(e) ~= "table" then return false end
  return e.type == errType or e.parentType == errType
end

local function makeDbError(code, msg)
  return {type="DbError:"..code, parentType="DbError", code=code, message=msg}
end

local err = makeDbError("TIMEOUT","query timed out")
print(isError(err, "DbError"))          -- true
print(isError(err, "DbError:TIMEOUT"))  -- true
print(isError(err, "NetworkError"))     -- false

त्रुटियों को लपेटना

पकड़कर दोबारा उठाते समय मूल त्रुटि को खोए बिना संदर्भ जोड़ने के लिए उसे लपेटें। आवरण का अपना प्रकार होता है और उसमें मूल त्रुटि कारण के रूप में रहती है।

local function wrapError(msg, cause)
  return {
    type = "WrappedError",
    message = msg,
    cause = cause,
  }
end

local function loadConfig(path)
  local ok, err = pcall(function()
    local f = assert(io.open(path,"r"))
    local content = f:read("a")
    f:close()
    return content
  end)
  if not ok then
    error(wrapError("failed to load config: "..path, err))
  end
end

local ok2, e = pcall(loadConfig, "missing.cfg")
if not ok2 then
  print(e.message)
  print("Caused by:", tostring(e.cause))
end

त्रुटि कोड बनाम त्रुटि प्रकार

दो सामान्य परंपराएँ हैं: त्रुटि कोड (संख्यात्मक, जैसे HTTP स्थिति कोड) और त्रुटि प्रकार स्ट्रिंग (अर्थपूर्ण नाम)। त्रुटि कोड की संख्यात्मक तुलना आसान होती है; प्रकार स्ट्रिंग स्वयं अपना अर्थ स्पष्ट करती हैं। कई प्रणालियाँ दोनों का उपयोग करती हैं।

local STATUS = {OK=200, NOT_FOUND=404, SERVER_ERROR=500, BAD_REQUEST=400}

local function makeStatusError(status, msg)
  return {status=status, message=msg, type="HTTPError"}
end

local function handleError(e)
  if e.status == STATUS.NOT_FOUND then
    print("Resource not found:", e.message)
  elseif e.status >= 500 then
    print("Server error:", e.message)
  else
    print("Error", e.status, e.message)
  end
end

handleError(makeStatusError(404, "user not found"))

त्रुटि स्टैक (कारण शृंखला)

जब कोई त्रुटि किसी दूसरी त्रुटि के कारण होती है, तो उन्हें शृंखला में जोड़ें। इससे अनुप्रयोग की प्रत्येक परत पर क्या गलत हुआ, इसका पूरा चित्र मिलता है। पूरी त्रुटि-कथा को लॉग या प्रदर्शित करने के लिए शृंखला को खोलें।

local function unwindCause(e, depth)
  depth = depth or 0
  local pad = string.rep("  ", depth)
  if type(e) == "table" then
    print(pad .. (e.type or "Error") .. ": " .. (e.message or "?"))
    if e.cause then unwindCause(e.cause, depth+1) end
  else
    print(pad .. tostring(e))
  end
end

local inner = {type="IoError", message="permission denied"}
local outer = {type="ConfigError", message="cannot load config", cause=inner}
unwindCause(outer)
-- ConfigError: cannot load config
--   IoError: permission denied

कॉलबैक संदर्भ में त्रुटि

जब कॉलबैक (इवेंट हैंडलर, इटरेटर) के भीतर त्रुटियाँ आती हैं, तो वे कॉलबैक को कॉल करने वाले तक फैलती हैं। उन्हें पकड़ने के लिए pcall का उपयोग करें और यह संदर्भ देते हुए रिपोर्ट करें कि कौन-सा कॉलबैक विफल हुआ।

local function runCallbacks(callbacks, data)
  local errors = {}
  for name, fn in pairs(callbacks) do
    local ok, err = pcall(fn, data)
    if not ok then
      errors[#errors+1] = {callback=name, error=err}
    end
  end
  return errors
end

local cbs = {
  validate = function(d) assert(d.name, "name required") end,
  transform = function(d) d.name = d.name:upper() end,
}

local errs = runCallbacks(cbs, {})
for _, e in ipairs(errs) do
  print(e.callback, "->", e.error)
end

त्रुटि विवरण प्रिंट करना

एक ऐसा सहायक जो त्रुटि ऑब्जेक्ट को संरचित और पढ़ने योग्य तरीके से प्रिंट करता है तथा स्ट्रिंग और टेबल, दोनों प्रकार की त्रुटियों को संभालता है। यह अनुप्रयोग की उन सीमाओं पर उपयोगी है जहाँ त्रुटियों को लॉग किया जाता है या उपयोगकर्ताओं को दिखाया जाता है।

local function printError(err, prefix)
  prefix = prefix or "Error"
  if type(err) ~= "table" then
    print(prefix .. ": " .. tostring(err))
    return
  end
  print(prefix .. " [" .. (err.type or "unknown") .. "]")
  print("  Message: " .. (err.message or "?"))
  for k, v in pairs(err) do
    if k ~= "type" and k ~= "message" and k ~= "cause" then
      print("  " .. k .. ": " .. tostring(v))
    end
  end
  if err.cause then printError(err.cause, "  Caused by") end
end

संरचित त्रुटियों के साथ अभिकथन

एक assertT बनाएँ (टाइपयुक्त त्रुटियों वाला assert), जो साधारण स्ट्रिंग के बजाय संरचित त्रुटि उठाए। इससे कॉल करने वाले में विशिष्ट त्रुटि प्रकारों की जाँच करना आसान हो जाता है।

local function assertT(cond, errType, msg, data)
  if not cond then
    local e = {type=errType, message=msg}
    if data then for k,v in pairs(data) do e[k]=v end end
    error(e, 2)
  end
  return cond
end

local function createUser(name, age)
  assertT(type(name)=="string", "BAD_INPUT", "name must be string", {field="name"})
  assertT(age >= 0 and age <= 150, "BAD_INPUT", "invalid age", {field="age", value=age})
  return {name=name, age=age}
end

local ok, err = pcall(createUser, "Alice", -5)
if not ok then print(err.type, err.field, err.value) end

त्वरित जाँच

स्ट्रिंग के बजाय error() में टेबल देने का मुख्य लाभ क्या है?

पुनरावलोकन: संरचित त्रुटियाँ

सारांश:

  • संरचित और जाँच योग्य त्रुटियों के लिए error() में टेबल दें
  • शामिल करें: प्रकार, संदेश और प्रासंगिक संदर्भ फ़ील्ड
  • पढ़ने योग्य आउटपुट के लिए __tostring जोड़ें
  • कारण खोए बिना संदर्भ जोड़ने के लिए त्रुटियों को लपेटें
  • हैंडलर में प्रकार के आधार पर वितरण करें: स्ट्रिंग पैटर्न के बजाय err.type जाँचें
शुरुआत निःशुल्क

एआई शिक्षक के साथ Lua सीखें — निःशुल्क

अपने ब्राउज़र में वास्तविक कोड लिखें और चलाएँ, चौबीसों घंटे एआई शिक्षक से तुरंत सहायता पाएँ, और वेब या ऐप पर वहीं से शुरू करें जहाँ आपने छोड़ा था।

पाठ्यक्रम
40
पाठ
159

अक्सर पूछे जाने वाले प्रश्न

क्या “संरचित त्रुटि ऑब्जेक्ट” पाठ निःशुल्क है?

हाँ — Lua Academy अध्ययन पथ के 3 तक कोई भी पाठ, जिसमें “संरचित त्रुटि ऑब्जेक्ट” भी शामिल है, यहाँ वेब पर पूरा पढ़ना निःशुल्क है। इसके बाद CoddyKit PRO हर पाठ अनलॉक करता है, साथ ही अंतर्निर्मित कोड संपादक और चौबीसों घंटे एआई शिक्षक के साथ इंटरैक्टिव अभ्यास भी उपलब्ध कराता है। Lua Academy पाठ्यक्रम में कुल 4 पाठ शामिल हैं।

“संरचित त्रुटि ऑब्जेक्ट” में मैं क्या सीखूँगा?

प्रकार और संदर्भ बताने के लिए टेबल को त्रुटि ऑब्जेक्ट के रूप में भेजें। आप ब्राउज़र में सीधे चलाए जाने वाले व्यावहारिक कोड के साथ Lua Academy का अभ्यास करते हैं, और पाठ पूरा करते समय 24/7 एआई ट्यूटर आपके प्रश्नों के उत्तर देता है।

क्या Lua Academy शुरू करने के लिए मुझे किसी अनुभव की आवश्यकता है?

पहले के अनुभव की आवश्यकता नहीं है। CoddyKit पर Lua Academy शुरुआती से लेकर उन्नत शिक्षार्थियों तक सभी के लिए व्यवस्थित किया गया है, इसलिए आप यहीं से या शुरुआत से सीखना शुरू कर सकते हैं और अपनी गति से आगे बढ़ सकते हैं। यह 4 में से 4वाँ पाठ है।

“संरचित त्रुटि ऑब्जेक्ट” पाठ पूरा करने में कितना समय लगता है?

CoddyKit का अधिकांश पाठ लगभग 5–10 मिनट में पूरा हो जाता है। हर पाठ छोटा और संवादात्मक है, इसलिए आप लगातार प्रगति करते हैं और वेब या ऐप पर वहीं से सीखना जारी रख सकते हैं जहाँ आपने छोड़ा था।

क्या मैं इस Lua Academy पाठ में कोड लिख और चला सकता हूँ?

हाँ। हर Lua Academy पाठ में एक अंतर्निर्मित कोड संपादक शामिल है, जिससे आप सीधे अपने ब्राउज़र में वास्तविक कोड लिख और चला सकते हैं और तुरंत एआई प्रतिक्रिया पा सकते हैं—स्थानीय सेटअप की आवश्यकता नहीं है।

इस पाठ्यक्रम के सभी पाठ

  1. error() फ़ंक्शन
  2. pcall से सुरक्षित कॉल
  3. xpcall और संदेश हैंडलर
  4. संरचित त्रुटि ऑब्जेक्ट
← Lua Academy पर वापस जाएँ