PCALL and XPCALL - Very useful

How pcall and xpcall works

by Isaque232

Author Avatar

Hello, I'll teach you about pcall and xpcall, It's very interesting and something very useful for any developer.

PCALL, how does it work:

pcall - protected call gets a function as It's argument, and runs it on 'protected' mode, which means any errors inside the function will not be propagated, pcall will catch the error and return a status code, the first returned argument will be a boolean, meaning if it did error or not ( true if it didn't error and false if it did ) and the second argument depends on the first, if it did error then the second argument will be the error message and if it didn't, It'll be what the function returned. Examples:

local sucess, msg = pcall(function()
  if "worked" == "worked" then -- is true
    return "Hey it worked"
  error("It isn't the same") -- will not error

print ("sucess = ",sucess)
print ("message = ",msg)

-- this prints:
-- sucess = true (means it didn't error)
-- message = "Hey it worked" (what the function returned)

Now if the pcall errors:

local sucess, msg = pcall(function()
  if "worked" == "orked" -- is false
    return "Hey it worked"
  error("It isn't the same") -- will error

print("sucess = ",sucess)
print("message = ",msg)

-- this prints:
-- sucess = false (means it did error)
-- and msg is the error message. (It isn't the same)

this is very useful so your whole script / game doesn't get interrupted because of some error, or for things like datastores to prevent data loss.

XPCALL, how does it work:

xpcall works the same way as pcall but it actually lets you control the error handler, means you can change the error message etc, by passing a second function argument as callback. It'll return the same error message like pcall but as an argument to that function, example:

local sucess, msg = xpcall(function()
  e("E doesn't exist which will error")
end, function (err) -- err is the error message
  print("Error message:", err)
  return ("Errored D:")

print ("sucess = ", sucess)
print ("Msg = ", msg)

-- this prints:
-- Error Message: attempt to call global 'e' (a nil value)
-- sucess = false (because it did error)
-- Msg = Errored D: (what returned from xpcall)

so you can do whatever you want with the error handler. Notice: You cannot yield xpcall.

This is basically it, this is my first tutorial so yeah, thanks for reading and hope you learned something new! :D

View in-game to comment, award, and more!