Protected Calls

Protected Calls [pcalls] help spot and manage errors in your Lua code

by fraiIstate

Author Avatar

Protected Calls [pcalls]

In Roblox - and Lua specifically - errors are inevitable. No matter how good you are, you will always end up with errors.

But what if I told you we can test a snippet for errors, and then decide whether not to continue dependent on the result? You heard me.

Let's take a look at this code, & then break it up after:

local function foo()
    return 2 * "bar"
end

pcall(foo)

The "foo" function would error, right? In theory, yes - but because we passed it into a pcall, the error won't interrupt the thread. As you can see, there is one problem with this approach. We don't know if our function ran successfully!

Fortunately, the pcall function will return two values! The first is a bool describing if the function was successful, and the second is either the value returned by the function or the error message if not successful. A common misconception is the second value will always be the error message, but that is not true - it will only return the error message if the function ran into an **ERROR.**If the function was successful, the second value would be whatever the function returned.

With that information, lets make our example a lot more useful!

local function foo()
    return 2 * "bar"
end

local success, msg = pcall(foo)
print(success, msg)

Upon running the above code, we can see it prints something along the lines of:

false attempt to perform arithmetic on a string value

It works! The first value is false and the second value is the error message, because the function was not successful.

Let's edit the example to make it work & see how the values returned will change:

local function foo()
    return 2 * 2
end

local success, msg = pcall(foo)
print(success, msg)

true 4

First value is true, second value is what was returned by the function (4, because 2*2 is 4)

Use Cases

Protected calls can be used for when a piece of code is subject to error. This includes datastore calls, tinkering with HTTPService, etc..

Practice

Mark has been looking after cats and dogs all day! He wrote up this handy piece of code to help him keep track but he wants to know if it works before he runs it. Can you use what you have learned in this tutorial to help Mark?

local Cats = {"Spotty", "Socksy"}
local Dogs = {"Ruff", "Scooby", "Marley"}

print(#Cats + Dogs)