Best practice for returning error from lua function returning multiple values

I have a lua function that takes several parameters and returns as many values ​​as there are parameters. Each return value corresponds to a parameter. To illustrate, consider a function that reads a value for a key / value pair from a database:

val1, val2, val3 = my_function("key1", "key2", "key3"); val1 = my_function("key1"); 

What is the best way to return an error from my_function ? (for example, if the supplied "key" is invalid)

I understand that one way is to return two values ​​on error, nil and the error string. Is this a better approach? For instance:

 val1, val2, val3 = my_function("key1", "key2", "key3"); if val1 then -- Use val1, val2, and val3. else print("ERROR: " .. val2); end 

Edit

Some additional points:

  • The lua script is executed from the C program using lua_pcall() .
  • C program should not be interrupted if the script fails.
  • my_function() is implemented in C.
  • When my_function() fails, it should also return an error code (or message) indicating the reason why it failed.
+6
source share
2 answers

The standard way to rollback errors in Lua is through the error function ( manual , api ) or through assert (which uses error anyway).

Since your function is in C, you must call lua_error inside it to get the same effect.

But keep in mind that now your function is "unsafe." If unmodified, the following code will execute the equivalent of a "throwing exception" and thus stop the program if key1, key2 or key3 is "wrong":

 val1, val2, val3 = my_function("key1", "key2", "key3") 

Sometimes this is normal if the program "just crashes" if the inputs are erroneous. Depending on your installation, the user will receive a message with the last error and a stack trace or something in that direction.

If "letting the program crash" is not an option, you can make the equivalent of the "try-catch" block surrounding it using pcall and adding a new variable called ok :

 ok, val1, val2, val3 = pcall(my_function, "key1", "key2", "key3") if ok then -- Use val1, val2, and val3. else print("ERROR: " .. val1) -- notice that we use val1 here, not val2 end 

Note that you do not need to put pcall exactly at the beginning of my_function . As with exceptions, error recovery can occur in the call chain above: in the function that calls my_function , or in the function that calls this, etc. For example, if you call my_function from a function called parent and a parent from one called grandParent , you can do this:

 -- parent is "insecure" since my_function is "unprotected" function parent(key1, key2) local val1, val2, val3 = my_function(key1, key2, "key3") return val1, val2, val3 end -- grandParent calls parent in a "safe" way function grandParent() local ok, val1, val2, val3 = pcall(parent, "key1", "key2") if ok then -- Use val1, val2, and val3. else print("ERROR: " .. val1) end end 
+6
source

A common practice is to throw errors when a program cannot recover (for example, a file descriptor), and signal errors when it can recover (a file was not found, for example). In your case, I think simply returning nil for invalid keys is the best way.

0
source

Source: https://habr.com/ru/post/905274/


All Articles