Alternative to FindFirstChild that errors instead of returning nil without possibly conflicting with API members

As a Roblox developer, it is currently too hard to get a child of an instance by its name without possibly conflicting with API members and error if the child doesn’t exist.

If this issue is addressed, it would improve my development experience because the current similar methods are all flawed for the use case of accessing a child that you know to exist with 100% certainty:

  • Instance[childName]
    This doesn’t solve my request as, if childName was an API member name, the API member would take priority over the child and cause an expected result of the operation evaluating to some method, property, or event instead of the child.

  • Instance:FindFirstChild
    This doesn’t solve my request as it doesn’t throw an error if the child doesn’t exist, and instead returns nil. This is a problem because when I expect children to certainly exist, I don’t design my code around the possibility of the method to get that child returning nil. Therefore, if the child doesn’t exist, I want the method to error to avoid weird/hard-to-track bugs in my code. In other words: I want to error now, not later.

  • Instance:WaitForChild
    This doesn’t solve my request as it yields if the child doesn’t exist. Unexpected yielding can cause problems, so I don’t want to allow that to potentially happen if I don’t expect it to.


My proposed solution is to add Instance:GetChild(childName: string) => Instance, which is used as such:

local Foo = require(ReplicatedStorage:GetChild("Modules"):GetChild("Shared"):GetChild("Foo"))

Foo.init()

local childThatDoesntExist = Workspace:GetChild("ChildThatDoesntExist") --> Errors

Child might be a better name than GetChild, since the method name will be typed out and used very often (probably the most used method). However, this alternate name would violate the stylistic consistency of method names being actions/verbs.

8 Likes

Another option is to use assert, which returns its arguments on success.

local Foo = require(assert(ReplicatedStorage:FindFirstChild("Foo")))
4 Likes

While this is an option, it’s more verbose, and you lose out on detailed error messages, unless you do this, which gives you a somewhat detailed error message (that GetChild could still provide more information than):

local NO_CHILD_ERROR = "Child doesn't exist"

local Foo = assert(
	assert(assert(ReplicatedStorage:FindFirstChild("Modules"), NO_CHILD_ERROR):FindFirstChild("Shared"), NO_CHILD_ERROR):FindFirstChild(
		"Foo"
	),
	NO_CHILD_ERROR
)

Foo.init()

v.s. the proposed solution:

local Foo = require(ReplicatedStorage:GetChild("Modules"):GetChild("Shared"):GetChild("Foo"))

Foo.init()
1 Like