### Incorrect Export Definition Examples Source: https://github.com/itsnoxius/lua-effect/blob/main/docs/implementation-guide.md These examples show common mistakes when defining exports. Avoid omitting `fx.wrap` and do not include a `self` parameter as FiveM does not pass it. ```lua -- WRONG: no fx.wrap exports('getUser', function(userId) ... end) -- WRONG: stripFirst / self (removed from API) exports('getUser', fx.wrap(function(self, userId) ... end, true)) ``` -------------------------------- ### Execute Pipelines with fx.pipeWith Source: https://context7.com/itsnoxius/lua-effect/llms.txt Similar to fx.pipe, but accepts a function as the initial argument instead of a value. Useful when the starting operation might fail. ```lua -- Initial function that may fail local function loadConfig() local data = LoadResourceFile(GetCurrentResourceName(), 'config.json') if not data or data == '' then return fx.err('Config not found') end local ok, cfg = pcall(json.decode, data) return ok and fx.ok(cfg) or fx.err('Invalid config') end local function getMaxPlayers(cfg) return cfg.maxPlayers and fx.ok(cfg.maxPlayers) or fx.err('maxPlayers not set') end local function validateRange(n) if n >= 1 and n <= 128 then return fx.ok(n) end return fx.err('maxPlayers out of range (1-128)') end -- pipeWith runs loadConfig() first, then pipes through transformations local configResult = fx.pipeWith(loadConfig, getMaxPlayers, validateRange) if fx.isOk(configResult) then print('Max players:', configResult.value) else print('Config error:', configResult.error) end ``` -------------------------------- ### Invoke exports with fx Source: https://github.com/itsnoxius/lua-effect/blob/main/README.md Use fx.invokeExportUnwrap to get values directly or fx.invokeExport to handle Result objects explicitly. ```lua local user = fx.invokeExportUnwrap('my-database', 'getUser', 123) -- If the export fails, you get the real error: "User not found: 123" ``` ```lua local result = fx.invokeExport('my-database', 'getUser', 123) if fx.isOk(result) then print('User:', result.value.name) else print('Error:', result.error) end ``` -------------------------------- ### Create Success Results with fx.ok Source: https://context7.com/itsnoxius/lua-effect/llms.txt Use fx.ok to wrap successful outcomes into a Result object. ```lua -- Create success results with any value type local userResult = fx.ok({ id = 123, name = 'Alice' }) local countResult = fx.ok(42) local listResult = fx.ok({ 'item1', 'item2', 'item3' }) -- Access the value print(userResult.value.name) -- "Alice" print(userResult.ok) -- true ``` -------------------------------- ### Initialize lua-effect Source: https://github.com/itsnoxius/lua-effect/blob/main/docs/getting-started.md Load the library using the require function. ```lua local fx = require('@lua-effect.fx') ``` -------------------------------- ### Simple Transform Chain with fx.pipe Source: https://github.com/itsnoxius/lua-effect/blob/main/README.md Demonstrates a basic transformation chain using fx.pipe, passing a value through multiple functions. ```lua fx.pipe(5, function(x) return x * 2 end, function(x) return x + 10 end) ``` -------------------------------- ### Get Error Metadata with fx.getErrorInfo Source: https://context7.com/itsnoxius/lua-effect/llms.txt fx.getErrorInfo retrieves parsed error metadata from a Result object if it represents a failure. This is a convenient shorthand for accessing the 'errorMeta' field. ```lua local result = fx.invokeExport('database', 'getUser', -1) local info = fx.getErrorInfo(result) if info then print('Error:', info.message) print('Resource:', info.resource) print('Location:', info.location) print('Line:', info.line) end ``` ```lua -- Use for detailed error logging local function handleResult(result, context) if fx.isOk(result) then return result.value end local info = fx.getErrorInfo(result) if info and info.resource then print(string.format('[%s] Error in %s at line %d: %s', context, info.resource, info.line or 0, info.message)) else print(string.format('[%s] Error: %s', context, result.error)) end return nil end ``` -------------------------------- ### fx.pipeWith Source: https://context7.com/itsnoxius/lua-effect/llms.txt Similar to fx.pipe, but the first argument is a function to call, useful when the initial step might fail. ```APIDOC ## fx.pipeWith ### Description Like fx.pipe but the first argument is a function to call, not a value. Useful when the initial step might fail (e.g., loading a file or resource). ### Parameters - **initialFn** (function) - Required - The function to execute first. - **...fns** (function) - Required - A series of functions to process the result of the initial function. ``` -------------------------------- ### fx.pipeWith for Initial Function Execution Source: https://github.com/itsnoxius/lua-effect/blob/main/README.md Illustrates using fx.pipeWith to execute an initial function before piping its result through subsequent functions. ```lua local cfg = fx.pipeWith(loadConfig, getMaxPlayers) ``` -------------------------------- ### Using fx.tryCall for One-off Blocks Source: https://github.com/itsnoxius/lua-effect/blob/main/README.md Illustrates using fx.tryCall to execute a block of code and capture its result, handling success or failure. ```lua local result = fx.tryCall(function() local json = LoadResourceFile(GetCurrentResourceName(), 'data.json') return json.decode(json) end) if fx.isOk(result) then use(result.value) else print('Parse failed:', result.error) end ``` -------------------------------- ### Creating Result Objects Source: https://github.com/itsnoxius/lua-effect/blob/main/docs/result-type.md Constructing success and error result objects using library helpers. ```lua local ok = fx.ok({ name = 'Alice' }) local err = fx.err('Something went wrong') ``` -------------------------------- ### Composing Operations with fx.andThen Source: https://github.com/itsnoxius/lua-effect/blob/main/README.md Demonstrates chaining operations using fx.andThen, where the second operation only runs if the first succeeds. ```lua local result = fx.tryCall(function() return GetUserInput() end) local processed = fx.andThen(result, function(user) return fx.tryCall(function() return validateAndSave(user) end) end) ``` -------------------------------- ### Create Safe Function Wrappers with fx.try Source: https://context7.com/itsnoxius/lua-effect/llms.txt Wraps a function to return a Result object instead of throwing exceptions. Ideal for creating reusable, safe versions of functions that might fail. ```lua -- Wrap a function that may throw local function parseConfig(filename) local data = LoadResourceFile(GetCurrentResourceName(), filename) assert(data, 'File not found: ' .. filename) return json.decode(data) end -- Create a safe version local safeParseConfig = fx.try(parseConfig) -- Use the safe version (always returns Result) local result = safeParseConfig('config.json') if fx.isOk(result) then print('Max players:', result.value.maxPlayers) else print('Config error:', result.error) end -- Reuse for multiple files local serverConfig = safeParseConfig('server.json') local gameConfig = safeParseConfig('game.json') ``` -------------------------------- ### Wrapping Exports with fx.wrap Source: https://github.com/itsnoxius/lua-effect/blob/main/README.md Demonstrates how to wrap an exported function using fx.wrap to ensure it returns a Result type, preserving errors. ```lua exports('getPlayerData', fx.wrap(function(playerId) local data = GetData(playerId) assert(data, 'Player not found') return data end)) ``` -------------------------------- ### Await Client Callback with fx.invoke Source: https://github.com/itsnoxius/lua-effect/blob/main/docs/exports-and-callbacks.md Await server callbacks on the client using `lib.callback.await` wrapped with `fx.invoke`. This returns a `Result` object, allowing for safe handling of callback responses. ```lua -- Client: await callback (wrap with fx.invoke for Result) local result = fx.invoke(lib.callback.await, 'myresource:getPlayerData', false, playerId) if fx.isOk(result) then use(result.value) end ``` -------------------------------- ### Handle cross-scope callbacks Source: https://github.com/itsnoxius/lua-effect/blob/main/README.md Use fx.wrap for server-side callback registration and fx.invoke for client-side callback awaiting. ```lua -- Server: lib.callback.register with fx.wrap lib.callback.register('myresource:getPlayerData', fx.wrap(function(source, playerId) assert(playerId, 'Player ID required') return GetPlayerData(playerId) end)) -- Client: lib.callback.await (wrap with fx.invoke for Result) local result = fx.invoke(lib.callback.await, 'myresource:getPlayerData', false, playerId) ``` -------------------------------- ### Register Server Callback with fx.wrap Source: https://github.com/itsnoxius/lua-effect/blob/main/docs/exports-and-callbacks.md Register server-side callbacks using `lib.callback.register` wrapped with `fx.wrap`. This ensures that any errors during callback execution are caught and returned as results. ```lua -- Server: register callback lib.callback.register('myresource:getPlayerData', fx.wrap(function(source, playerId) assert(playerId, 'Player ID required') return GetPlayerData(playerId) end)) ``` -------------------------------- ### Configure fxmanifest.lua dependencies Source: https://github.com/itsnoxius/lua-effect/blob/main/docs/getting-started.md Add lua-effect and its dependencies to your resource manifest to enable the library. ```lua fx_version 'cerulean' game 'gta5' dependencies { 'ox_lib', 'lua-effect', } shared_scripts { '@ox_lib/init.lua', '@lua-effect/fx.lua', } ``` -------------------------------- ### Result Short-circuiting with fx.pipe Source: https://github.com/itsnoxius/lua-effect/blob/main/README.md Shows how fx.pipe short-circuits execution when a function returns a Result error. ```lua local result = fx.pipe(jsonStr, parseJson, function(d) return getField(d, 'count') end, validatePositive) ``` -------------------------------- ### fx.ok - Create Success Result Source: https://context7.com/itsnoxius/lua-effect/llms.txt Creates a success Result containing the provided value. Use this to explicitly return successful outcomes from functions that participate in the Result-based error handling flow. ```APIDOC ## fx.ok ### Description Creates a success Result containing the provided value. Use this to explicitly return successful outcomes from functions that participate in the Result-based error handling flow. ### Method N/A (Function call) ### Endpoint N/A ### Parameters None ### Request Example ```lua -- Create success results with any value type local userResult = fx.ok({ id = 123, name = 'Alice' }) local countResult = fx.ok(42) local listResult = fx.ok({ 'item1', 'item2', 'item3' }) -- Access the value print(userResult.value.name) -- "Alice" print(userResult.ok) -- true ``` ### Response #### Success Response (Result Type) - **value** (any) - The successful value contained within the Result. - **ok** (boolean) - Always true for a success Result. #### Response Example ```json { "value": { "id": 123, "name": "Alice" }, "ok": true } ``` ``` -------------------------------- ### Integrate ox_lib Callbacks with fx.wrap and fx.invoke Source: https://context7.com/itsnoxius/lua-effect/llms.txt Wrap server-side callback handlers with fx.wrap for proper error propagation. Use fx.invoke on the client to await callbacks and handle Results, ensuring robust communication. ```lua -- Server: register callback with fx.wrap lib.callback.register('myresource:getPlayerData', fx.wrap(function(source, playerId) assert(playerId, 'Player ID required') assert(playerId > 0, 'Invalid player ID') local player = GetPlayerData(playerId) assert(player, 'Player not found: ' .. playerId) return player end)) ``` ```lua -- Client: await callback with fx.invoke for Result handling local result = fx.invoke(lib.callback.await, 'myresource:getPlayerData', false, playerId) if fx.isOk(result) then local player = result.value print('Player name:', player.name) print('Player level:', player.level) else print('Failed to get player data:', result.error) end ``` ```lua -- Alternative: use invokeUnwrap if you want errors to throw local player = fx.invokeUnwrap(lib.callback.await, 'myresource:getPlayerData', false, playerId) ``` -------------------------------- ### Invoke local functions with fx Source: https://github.com/itsnoxius/lua-effect/blob/main/README.md Use fx.invoke to execute local functions and receive a Result object with proper error messages. ```lua local function loadConfig(path) local data = LoadResourceFile(GetCurrentResourceName(), path) assert(data, 'Config not found: ' .. path) return json.decode(data) end -- Direct call: normal return/throw local config = loadConfig('config.json') -- Via fx.invoke: Result with proper error message local result = fx.invoke(loadConfig, 'config.json') if fx.isOk(result) then use(result.value) end ``` -------------------------------- ### Manifest Dependencies Source: https://github.com/itsnoxius/lua-effect/blob/main/docs/implementation-guide.md Ensure that `ox_lib` and `lua-effect` are listed in your `fx_manifest.lua` dependencies and included as shared scripts. ```lua dependencies { 'ox_lib', 'lua-effect', } shared_scripts { '@ox_lib/init.lua', '@lua-effect/fx.lua', } ``` -------------------------------- ### Try (Wrapping Errors/Asserts) Source: https://github.com/itsnoxius/lua-effect/blob/main/docs/api-reference.md Functions for wrapping potentially throwing functions to return Results. ```APIDOC ## Try (Wrapping error/assert) ### `fx.try(fn: (...any) -> any) -> (...any) -> Result` Wraps a function so that it returns a `Result` type instead of throwing errors. ### `fx.tryCall(fn: () -> any) -> Result` Executes a function once and returns its result as a `Result` type. ``` -------------------------------- ### Provide Fallbacks with fx.unwrapOr Source: https://context7.com/itsnoxius/lua-effect/llms.txt Return a default value if the Result is a failure, avoiding thrown errors. ```lua -- Returns value on success local successResult = fx.ok(100) local value = fx.unwrapOr(successResult, 0) print(value) -- 100 -- Returns default on failure local errorResult = fx.err('Not found') local value = fx.unwrapOr(errorResult, 0) print(value) -- 0 -- Practical usage with configuration local configResult = fx.invokeExport('config', 'getMaxPlayers') local maxPlayers = fx.unwrapOr(configResult, 32) -- Default to 32 if config fails ``` -------------------------------- ### Export functions with fx.wrap Source: https://github.com/itsnoxius/lua-effect/blob/main/README.md Wrap exported functions to ensure errors propagate as values across resource boundaries. ```lua -- In your database resource exports('getUser', fx.wrap(function(userId) local user = GetUserFromDb(userId) assert(user, 'User not found: ' .. tostring(userId)) return user end)) ``` -------------------------------- ### ox_lib Callback Integration Source: https://context7.com/itsnoxius/lua-effect/llms.txt Integrates with ox_lib callbacks for server-client communication. Use `fx.wrap` to wrap callback handlers and `fx.invoke` to await callbacks, ensuring proper Result handling. ```APIDOC ## ox_lib Callback Integration ### Description fx integrates with ox_lib callbacks for server-client communication. Wrap callback handlers with `fx.wrap` and use `fx.invoke` when awaiting callbacks. ### Method - `fx.wrap(callbackFunction)`: Wraps a function to handle Result propagation. - `fx.invoke(awaitFunction, ...)`: Awaits a callback function, returning a Result. - `fx.invokeUnwrap(awaitFunction, ...)`: Awaits a callback function, unwrapping the Result or throwing an error. ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```lua -- Server: register callback with fx.wrap lib.callback.register('myresource:getPlayerData', fx.wrap(function(source, playerId) assert(playerId, 'Player ID required') assert(playerId > 0, 'Invalid player ID') local player = GetPlayerData(playerId) assert(player, 'Player not found: ' .. playerId) return player end)) -- Client: await callback with fx.invoke for Result handling local result = fx.invoke(lib.callback.await, 'myresource:getPlayerData', false, playerId) if fx.isOk(result) then local player = result.value print('Player name:', player.name) print('Player level:', player.level) else print('Failed to get player data:', result.error) end -- Alternative: use invokeUnwrap if you want errors to throw local player = fx.invokeUnwrap(lib.callback.await, 'myresource:getPlayerData', false, playerId) ``` ### Response #### Success Response (200) - **value** (any) - The successful return value of the callback. #### Error Response - **error** (string) - The error message if the callback failed. - **errorMeta** (object, optional) - Structured metadata about the error. #### Response Example (Success) ```json { "value": { "name": "PlayerName", "level": 10 } } ``` #### Response Example (Error) ```json { "error": "Player not found: 123", "errorMeta": { "message": "Player not found: 123", "resource": "myresource", "line": 50 } } ``` ``` -------------------------------- ### fx.try Source: https://context7.com/itsnoxius/lua-effect/llms.txt Wraps a function so it always returns a Result instead of throwing, useful for creating reusable safe versions of functions. ```APIDOC ## fx.try ### Description Wraps a function so it always returns a Result instead of throwing. Unlike fx.wrap (for exports), fx.try is for creating reusable safe versions of functions. ### Parameters - **fn** (function) - Required - The function to wrap. ``` -------------------------------- ### Call Export (Raw) Source: https://github.com/itsnoxius/lua-effect/blob/main/docs/exports-and-callbacks.md Invoke exports directly using the `exports` table for raw calls. This method retains FiveM's default behavior, which may result in generic error messages. ```lua local user = exports['my-resource']:getUser(123) -- Returns value or throws; FiveM may show generic error message ``` -------------------------------- ### Pipelining Operations Source: https://github.com/itsnoxius/lua-effect/blob/main/docs/result-type.md Chaining multiple operations with automatic short-circuiting on error. ```lua local result = fx.pipe( jsonStr, parseJson, function(d) return getField(d, 'count') end, validatePositive ) ``` ```lua local cfg = fx.pipeWith(loadConfig, getMaxPlayers) ``` -------------------------------- ### Create Failure Results with fx.err Source: https://context7.com/itsnoxius/lua-effect/llms.txt Use fx.err to wrap error messages, which are automatically parsed for metadata. ```lua -- Create error results local notFound = fx.err('User not found') local validationErr = fx.err('Invalid user ID: -1') -- Error with FiveM-style location (automatically parsed) local detailedErr = fx.err('@my-resource/server.lua:42: Database connection failed') -- Access error info print(notFound.error) -- "User not found" print(notFound.ok) -- false print(detailedErr.errorMeta.resource) -- "my-resource" print(detailedErr.errorMeta.line) -- 42 ``` -------------------------------- ### Check Result Status with fx.isOk and fx.isErr Source: https://context7.com/itsnoxius/lua-effect/llms.txt Use these functions to conditionally handle success or failure states of a Result. ```lua local result = fx.invokeExport('database', 'getUser', 123) if fx.isOk(result) then local user = result.value print('Found user:', user.name) else print('Error occurred:', result.error) if result.errorMeta then print(' At:', result.errorMeta.location) end end -- Alternative pattern with isErr if fx.isErr(result) then -- Handle error case first return nil end -- Continue with success case local user = result.value ``` -------------------------------- ### Await ox_lib Callback with fx.invoke Source: https://github.com/itsnoxius/lua-effect/blob/main/docs/implementation-guide.md Use `fx.invoke` with `lib.callback.await` to safely await a remote callback. This returns a Result object, allowing for error checking. ```lua -- Client (with Result) local result = fx.invoke(lib.callback.await, 'name', false, playerId) ``` -------------------------------- ### fx.andThen Source: https://context7.com/itsnoxius/lua-effect/llms.txt Chains Result-returning functions sequentially. If the preceding Result is a success, its value is passed to the next function. Errors propagate immediately. ```APIDOC ## fx.andThen ### Description Chains Result-returning functions. If the first Result is success, passes its value to the function and returns its Result. If failure, the error propagates. Essential for sequential operations that each might fail. ### Method N/A (Function) ### Endpoint N/A ### Parameters #### Path Parameters N/A #### Query Parameters N/A #### Request Body N/A ### Request Example ```lua -- Chain dependent operations local function loadUser(userId) return fx.invokeExport('database', 'getUser', userId) end local function validateUser(user) if user.banned then return fx.err('User is banned') end return fx.ok(user) end local function loadUserInventory(user) return fx.invokeExport('inventory', 'getItems', user.id) end -- Chain all three operations local result = fx.andThen( fx.andThen(loadUser(123), validateUser), loadUserInventory ) if fx.isOk(result) then print('Inventory items:', #result.value) else print('Failed:', result.error) -- Could be from any step end ``` ### Response #### Success Response (200) N/A (Returns a new Result) #### Response Example N/A ``` -------------------------------- ### Register ox_lib Callback with fx.wrap Source: https://github.com/itsnoxius/lua-effect/blob/main/docs/implementation-guide.md When registering callbacks with `ox_lib`, wrap the callback function with `fx.wrap` to ensure it integrates correctly with lua-effect's error handling. ```lua -- Server lib.callback.register('name', fx.wrap(function(source, playerId) return GetData(playerId) end)) ``` -------------------------------- ### Recover from Failures Source: https://context7.com/itsnoxius/lua-effect/llms.txt Provides a fallback mechanism for failure Results. If the initial Result is a success, it is returned as-is. ```lua -- Provide fallback on failure local function loadFromCache(key) return fx.invokeExport('cache', 'get', key) end local function loadFromDatabase(key) return fx.invokeExport('database', 'get', key) end -- Try cache first, fall back to database local result = fx.orElse(loadFromCache('user:123'), function(cacheErr) print('Cache miss:', cacheErr) return loadFromDatabase('user:123') end) -- Provide default value on any failure local configResult = fx.orElse( fx.invokeExport('config', 'get', 'maxPlayers'), function(err) return fx.ok(32) end -- Default to 32 ) ``` -------------------------------- ### Invoke FiveM Exports with fx.invokeExportUnwrap Source: https://context7.com/itsnoxius/lua-effect/llms.txt Calls a FiveM export and returns the value directly, throwing an error if the operation fails. Use this to allow exceptions to propagate naturally. ```lua -- Direct value access (throws on error) local user = fx.invokeExportUnwrap('my-database', 'getUser', 123) print('User:', user.name) -- Use with pcall for manual error handling local ok, result = pcall(fx.invokeExportUnwrap, 'my-database', 'getUser', -1) if ok then print('User:', result.name) else print('Error:', result) -- Actual error message, not generic FiveM error end -- Chain of export calls (any failure throws) local function getPlayerData(playerId) local user = fx.invokeExportUnwrap('database', 'getUser', playerId) local inventory = fx.invokeExportUnwrap('inventory', 'getItems', playerId) local balance = fx.invokeExportUnwrap('economy', 'getBalance', playerId) return { user = user, inventory = inventory, balance = balance } end exports('getPlayerData', fx.wrap(getPlayerData)) ``` -------------------------------- ### Wrap functions with fx.wrap Source: https://context7.com/itsnoxius/lua-effect/llms.txt Wraps functions to catch errors and return a Result object, which is required for FiveM exports to propagate errors correctly. ```lua -- Define exports with proper error propagation exports('getUser', fx.wrap(function(userId) assert(userId and userId > 0, 'Invalid user ID: ' .. tostring(userId)) local user = GetUserFromDatabase(userId) assert(user, 'User not found: ' .. tostring(userId)) return user end)) exports('divide', fx.wrap(function(a, b) assert(b ~= nil, 'Missing divisor') assert(b ~= 0, 'Cannot divide by zero') return a / b end)) exports('transferMoney', fx.wrap(function(fromId, toId, amount) assert(amount > 0, 'Amount must be positive') local sender = fx.invokeUnwrap(getPlayer, fromId) local receiver = fx.invokeUnwrap(getPlayer, toId) assert(sender.balance >= amount, 'Insufficient funds') sender.balance = sender.balance - amount receiver.balance = receiver.balance + amount return { from = sender.balance, to = receiver.balance } end)) ``` -------------------------------- ### Export a function with fx.wrap Source: https://github.com/itsnoxius/lua-effect/blob/main/docs/getting-started.md Wrap an export function to ensure errors are captured and returned as a Result object. ```lua exports('getUser', fx.wrap(function(userId) local user = GetUserFromDb(userId) assert(user, 'User not found: ' .. tostring(userId)) return user end)) ``` -------------------------------- ### Unwrap Results with fx.unwrap Source: https://context7.com/itsnoxius/lua-effect/llms.txt Extract the value from a success Result or throw an error if it is a failure. ```lua -- Unwrap success - returns the value local successResult = fx.ok({ name = 'Alice' }) local user = fx.unwrap(successResult) print(user.name) -- "Alice" -- Unwrap failure - throws with error message local errorResult = fx.err('User not found') local user = fx.unwrap(errorResult) -- throws: "User not found" -- Practical usage in chained calls local function processUser(userId) local user = fx.unwrap(fx.invokeExport('database', 'getUser', userId)) local balance = fx.unwrap(fx.invokeExport('economy', 'getBalance', userId)) return { user = user, balance = balance } end ``` -------------------------------- ### Invoke local functions with fx.invoke Source: https://context7.com/itsnoxius/lua-effect/llms.txt Executes local functions and returns a Result object, allowing for safe error handling without throwing exceptions. ```lua -- Local helper functions local function validateInput(data) assert(data.name, 'Name is required') assert(#data.name >= 2, 'Name too short') return data end local function processData(data) assert(data.value > 0, 'Value must be positive') return data.value * 2 end -- Invoke and handle Result local result = fx.invoke(validateInput, { name = 'A' }) if fx.isErr(result) then print('Validation failed:', result.error) -- "Name too short" end -- Chain local invocations local input = { name = 'Test', value = 10 } local validated = fx.invoke(validateInput, input) if fx.isOk(validated) then local processed = fx.invoke(processData, validated.value) if fx.isOk(processed) then print('Result:', processed.value) -- 20 end end ``` -------------------------------- ### Execute One-off Operations with fx.tryCall Source: https://context7.com/itsnoxius/lua-effect/llms.txt Executes a function once and returns a Result object. Use for operations that might throw without needing a reusable wrapper. ```lua -- One-off JSON parsing local result = fx.tryCall(function() local data = LoadResourceFile(GetCurrentResourceName(), 'data.json') return json.decode(data) end) if fx.isOk(result) then for _, item in ipairs(result.value.items) do print('Item:', item.name) end else print('Failed to load data:', result.error) end -- Inline validation local input = { count = -5 } local validated = fx.tryCall(function() assert(input.count > 0, 'Count must be positive') return input.count end) local count = fx.unwrapOr(validated, 1) -- Default to 1 on failure ``` -------------------------------- ### Unwrap local calls with fx.invokeUnwrap Source: https://context7.com/itsnoxius/lua-effect/llms.txt Executes local functions and returns the raw value, propagating errors by throwing if they occur. ```lua -- Local helpers that may fail local function validateUserId(userId) assert(userId and userId > 0, 'Invalid user ID') return userId end local function fetchUser(userId) local id = fx.invokeUnwrap(validateUserId, userId) return { id = id, name = 'User ' .. id } end local function getBalance(userId) local user = fx.invokeUnwrap(fetchUser, userId) return user.id * 100 -- Simulated balance end -- Use in export (errors propagate automatically) exports('getUserWithBalance', fx.wrap(function(userId) local user = fx.invokeUnwrap(fetchUser, userId) local balance = fx.invokeUnwrap(getBalance, userId) return { user = user, balance = balance } end)) ``` -------------------------------- ### Accessing Error Metadata Source: https://github.com/itsnoxius/lua-effect/blob/main/docs/error-handling.md Demonstrates checking for errors and accessing metadata fields after an export invocation. ```lua local result = fx.invokeExport('my-resource', 'divide', 10, 0) if fx.isErr(result) then print(result.error) -- "Missing divisor" or "Cannot divide by zero" if result.errorMeta then print(' Resource:', result.errorMeta.resource) print(' Line:', result.errorMeta.line) print(' Location:', result.errorMeta.location) end end ``` -------------------------------- ### Pipeline Utilities Source: https://github.com/itsnoxius/lua-effect/blob/main/README.md Functions for chaining operations and short-circuiting on errors. ```APIDOC ## Pipeline Utilities ### Description Allows passing values through a series of functions, short-circuiting if a Result error is encountered. ### Functions - **fx.pipe(value, fn1, fn2, ...)** - Pass value through fn1, then fn2, etc. - **fx.pipeWith(fn, fn1, fn2, ...)** - Run fn() first, then pipe its result through the rest ``` -------------------------------- ### Call exports with fx.invokeExport Source: https://context7.com/itsnoxius/lua-effect/llms.txt Invokes FiveM exports from other resources and returns a Result, preserving detailed error metadata. ```lua -- Basic export call with Result handling local result = fx.invokeExport('my-database', 'getUser', 123) if fx.isOk(result) then local user = result.value print('Found user:', user.name) else print('Error:', result.error) -- Access detailed error metadata if available if result.errorMeta then print(' Resource:', result.errorMeta.resource) print(' File:', result.errorMeta.file) print(' Line:', result.errorMeta.line) end end -- Multiple export calls with proper error handling local userResult = fx.invokeExport('database', 'getUser', playerId) if fx.isErr(userResult) then return print('User error:', userResult.error) end local inventoryResult = fx.invokeExport('inventory', 'getItems', playerId) if fx.isErr(inventoryResult) then return print('Inventory error:', inventoryResult.error) end print('User:', userResult.value.name, 'Items:', #inventoryResult.value) ``` -------------------------------- ### fx.invokeExportUnwrap Source: https://context7.com/itsnoxius/lua-effect/llms.txt Calls a FiveM export and returns the value directly, or throws with the actual error message if it fails. ```APIDOC ## fx.invokeExportUnwrap ### Description Calls a FiveM export and returns the value directly, or throws with the actual error message if it fails. Use when you want exceptions to propagate naturally. ### Parameters - **resourceName** (string) - Required - The name of the resource providing the export. - **exportName** (string) - Required - The name of the export function. - **...args** (any) - Optional - Arguments to pass to the export function. ``` -------------------------------- ### FiveM Exports & Local Invoke Source: https://github.com/itsnoxius/lua-effect/blob/main/docs/api-reference.md Functions for safely invoking local functions and FiveM exports. ```APIDOC ## FiveM Exports & Local Invoke ### `fx.wrap(fn: (...any) -> any) -> (...any) -> any` Wraps a function for exports or callbacks. It catches throws and returns `Result.err`. This prevents FiveM from logging 'SCRIPT ERROR' in the called resource. ### `fx.invoke(fn: function, ...any) -> Result` Calls a local function and returns the result as a `Result` type. ### `fx.invokeUnwrap(fn: function, ...any) -> any` Calls a local function and returns its value, or throws an error if it fails. ### `fx.invokeExport(resource: string, export: string, ...any) -> Result` Calls a specified export function in another resource and returns the result as a `Result` type. ### `fx.invokeExportUnwrap(resource: string, export: string, ...any) -> any` Calls a specified export function in another resource and returns its value, or throws an error if it fails. ``` -------------------------------- ### Parse FiveM Error Strings with fx.parseError Source: https://context7.com/itsnoxius/lua-effect/llms.txt Use fx.parseError to convert raw FiveM error strings into structured metadata including message, location, file, line number, and resource name. Handles both detailed and simple error messages. ```lua -- Parse FiveM error format local parsed = fx.parseError('@example_resource/server.lua:42: Something went wrong') print(parsed.message) -- "Something went wrong" print(parsed.location) -- "@example_resource/server.lua:42" print(parsed.file) -- "@example_resource/server.lua" print(parsed.line) -- 42 print(parsed.resource) -- "example_resource" -- Handle various error formats local simple = fx.parseError('Simple error message') print(simple.message) -- "Simple error message" print(simple.line) -- nil (no location info) ``` ```lua -- Use for logging local function logError(result) if fx.isErr(result) then local info = result.errorMeta or fx.parseError(result.error) print(string.format('[ERROR] %s at %s:%d', info.message, info.resource or 'unknown', info.line or 0 )) end end ``` -------------------------------- ### Try and Error Handling Source: https://github.com/itsnoxius/lua-effect/blob/main/README.md Utilities for wrapping functions that might throw errors into Result objects. ```APIDOC ## Try and Error Handling ### Description Wraps functions that throw errors into Result objects and provides parsing for error messages. ### Functions - **fx.try(fn)** - Wrap a function so it returns a Result instead of throwing - **fx.tryCall(fn)** - Run a function once and return a Result - **fx.parseError(message)** - Parse error into { message, location?, file?, line? } - **fx.getErrorInfo(result)** - For failed results, returns parsed error info ``` -------------------------------- ### Call Export (Result-based) Source: https://github.com/itsnoxius/lua-effect/blob/main/docs/exports-and-callbacks.md Use `fx.invokeExport` for result-based calls, which returns a `Result` object. Check `fx.isOk` to determine success and access `result.value` or `result.error`. ```lua local result = fx.invokeExport('my-resource', 'getUser', 123) if fx.isOk(result) then print(result.value.name) else print('Error:', result.error) if result.errorMeta then print(' Resource:', result.errorMeta.resource, 'Line:', result.errorMeta.line) end end ``` -------------------------------- ### Result Type Utilities Source: https://github.com/itsnoxius/lua-effect/blob/main/README.md Functions for creating, checking, and unwrapping Result objects. ```APIDOC ## Result Type Utilities ### Description Functions to manage Result objects, allowing for success/failure state handling and safe value extraction. ### Functions - **fx.ok(value)** - Create a success result - **fx.err(message)** - Create a failure result - **fx.isOk(result)** - Returns true if result is success - **fx.isErr(result)** - Returns true if result is failure - **fx.unwrap(result)** - Return value or throw with the error message - **fx.assertResult(result, msg?)** - Return value or throw (optional custom message) - **fx.unwrapOr(result, default)** - Return value or default on failure - **fx.map(result, fn)** - Apply fn to the value if success - **fx.andThen(result, fn)** - Chain: if success, run fn(value) and return its result - **fx.orElse(result, fn)** - Recover: if failure, run fn(error) and return its result ``` -------------------------------- ### fx.orElse Source: https://context7.com/itsnoxius/lua-effect/llms.txt Recovers from a failure by executing an alternative function. If the initial Result is a success, it's returned unchanged. If it's a failure, the error is passed to the recovery function. ```APIDOC ## fx.orElse ### Description Recovers from a failure by running an alternative function. If the Result is success, returns it unchanged. If failure, passes the error to the function which returns a new Result. ### Method N/A (Function) ### Endpoint N/A ### Parameters #### Path Parameters N/A #### Query Parameters N/A #### Request Body N/A ### Request Example ```lua -- Provide fallback on failure local function loadFromCache(key) return fx.invokeExport('cache', 'get', key) end local function loadFromDatabase(key) return fx.invokeExport('database', 'get', key) end -- Try cache first, fall back to database local result = fx.orElse(loadFromCache('user:123'), function(cacheErr) print('Cache miss:', cacheErr) return loadFromDatabase('user:123') end) -- Provide default value on any failure local configResult = fx.orElse( fx.invokeExport('config', 'get', 'maxPlayers'), function(err) return fx.ok(32) end -- Default to 32 ) ``` ### Response #### Success Response (200) N/A (Returns a new Result) #### Response Example N/A ``` -------------------------------- ### fx.tryCall Source: https://context7.com/itsnoxius/lua-effect/llms.txt Executes a function once and returns a Result, suitable for one-off operations that might throw. ```APIDOC ## fx.tryCall ### Description Executes a function once and returns a Result. Use for one-off operations that might throw, without creating a reusable wrapper. ### Parameters - **fn** (function) - Required - The function to execute. ``` -------------------------------- ### Unwrapping Result Values Source: https://github.com/itsnoxius/lua-effect/blob/main/docs/result-type.md Methods to extract values from results, including error propagation and default value handling. ```lua -- Throw on error (use when you want to propagate) local value = fx.unwrap(result) -- Default on error local value = fx.unwrapOr(result, defaultValue) -- Custom message when throwing local value = fx.assertResult(result, 'Custom error message') ``` -------------------------------- ### Nested Local Calls with fx.invokeUnwrap Source: https://github.com/itsnoxius/lua-effect/blob/main/docs/exports-and-callbacks.md Use `fx.invokeUnwrap` for nested local function calls. This ensures that errors from called functions are propagated and thrown, simplifying the control flow. ```lua local function validateId(id) assert(id and id > 0, 'Invalid ID') return id end local function fetchUser(id) local validId = fx.invokeUnwrap(validateId, id) return { id = validId, name = 'User ' .. validId } end exports('getUser', fx.wrap(function(userId) return fx.invokeUnwrap(fetchUser, userId) end)) ``` -------------------------------- ### Call Export (Unwrap) Source: https://github.com/itsnoxius/lua-effect/blob/main/docs/exports-and-callbacks.md Use `fx.invokeExportUnwrap` to call an export. This method will throw an error with the actual message if the export fails, simplifying error handling when exceptions are preferred. ```lua local user = fx.invokeExportUnwrap('my-resource', 'getUser', 123) -- Throws with real error message if export fails ``` -------------------------------- ### fx.pipe Source: https://context7.com/itsnoxius/lua-effect/llms.txt Passes a value through a series of functions, automatically handling Result types and short-circuiting on errors. ```APIDOC ## fx.pipe ### Description Passes a value through a series of functions, automatically handling Result types. Short-circuits on the first error, returning the failure Result. ### Parameters - **initialValue** (any) - Required - The starting value. - **...fns** (function) - Required - A series of functions to process the value. ``` -------------------------------- ### Parsing Raw Error Strings Source: https://github.com/itsnoxius/lua-effect/blob/main/docs/error-handling.md Manually parsing an arbitrary error string into a structured metadata table. ```lua local parsed = fx.parseError("@resource/file.lua:42: Some error") -- { message = "Some error", location = "...", file = "...", line = 42, resource = "resource" } ``` -------------------------------- ### FiveM Exports & Invocation Source: https://github.com/itsnoxius/lua-effect/blob/main/README.md Functions for safely invoking local functions and FiveM exports with error handling. ```APIDOC ## FiveM Exports & Invocation ### Description Utilities to wrap exports and callbacks to preserve error messages across resource boundaries. ### Functions - **fx.wrap(fn)** - Wrap for exports/callbacks; catches throws, returns Result.err - **fx.invoke(fn, ...)** - Call a local function, return Result - **fx.invokeUnwrap(fn, ...)** - Call a local function, return value or throw on error - **fx.invokeExport(resource, export, ...)** - Call an export, return Result - **fx.invokeExportUnwrap(resource, export, ...)** - Call an export, return value or throw on error ``` -------------------------------- ### Try-Catch Wrappers Source: https://github.com/itsnoxius/lua-effect/blob/main/docs/result-type.md Wrapping functions or blocks that may throw exceptions into Result objects. ```lua local result = fx.tryCall(function() local json = LoadResourceFile(GetCurrentResourceName(), 'data.json') return json.decode(json) end) ``` ```lua local safeLoad = fx.try(loadConfig) local result = safeLoad('config.json') ``` -------------------------------- ### Transforming Results Source: https://github.com/itsnoxius/lua-effect/blob/main/docs/result-type.md Utility functions for mapping success values, transforming errors, and chaining operations. ```lua local nameResult = fx.map(userResult, function(user) return user.name end) ``` ```lua local friendly = fx.mapErr(result, function(err) return 'Failed: ' .. err end) ``` ```lua local result = fx.andThen(loadUser(123), function(user) return saveUser(user) end) ``` ```lua local result = fx.orElse(failedResult, function(err) return fx.ok(getDefaultValue()) end) ``` -------------------------------- ### Chain Result Operations Source: https://context7.com/itsnoxius/lua-effect/llms.txt Sequentially chains functions that return Results. If any step fails, the error propagates. ```lua -- Chain dependent operations local function loadUser(userId) return fx.invokeExport('database', 'getUser', userId) end local function validateUser(user) if user.banned then return fx.err('User is banned') end return fx.ok(user) end local function loadUserInventory(user) return fx.invokeExport('inventory', 'getItems', user.id) end -- Chain all three operations local result = fx.andThen( fx.andThen(loadUser(123), validateUser), loadUserInventory ) if fx.isOk(result) then print('Inventory items:', #result.value) else print('Failed:', result.error) -- Could be from any step end ``` -------------------------------- ### Nested function invocation Source: https://github.com/itsnoxius/lua-effect/blob/main/README.md Local functions can call each other using fx.invokeUnwrap to maintain error propagation. ```lua local function validateId(id) assert(id and id > 0, 'Invalid ID') return id end local function fetchUser(id) local validId = fx.invokeUnwrap(validateId, id) return { id = validId, name = 'User ' .. validId } end -- Export uses nested local calls exports('getUser', fx.wrap(function(userId) return fx.invokeUnwrap(fetchUser, userId) end)) ``` -------------------------------- ### Retrieving Error Info Source: https://github.com/itsnoxius/lua-effect/blob/main/docs/error-handling.md Using the helper function to extract error information from a result object. ```lua local info = fx.getErrorInfo(result) if info then print(info.message, info.resource, info.line) end ``` -------------------------------- ### Pipeline Operations Source: https://github.com/itsnoxius/lua-effect/blob/main/docs/api-reference.md Functions for creating data processing pipelines. ```APIDOC ## Pipeline ### `fx.pipe(value: any, ...fn: (any) -> any) -> any` Passes a `value` through a series of functions (`fn`). The pipeline short-circuits and returns an error if any function in the chain returns a `Result` error. ### `fx.pipeWith(fn: () -> any, ...transform: (any) -> any) -> any` First, executes the initial function `fn()`, then pipes its result through the subsequent transformation functions (`transform`). Short-circuits on `Result` errors. ``` -------------------------------- ### Call and Unwrap a Remote Export with lua-effect Source: https://github.com/itsnoxius/lua-effect/blob/main/docs/README.md Use `fx.invokeExportUnwrap` to call a remote export and automatically unwrap the `Result`. If the `Result` is an error, this function will throw an exception. ```lua fx.invokeExportUnwrap('resource', 'name', arg) ``` -------------------------------- ### Define Export with fx.wrap Source: https://github.com/itsnoxius/lua-effect/blob/main/docs/implementation-guide.md Always wrap exported functions with `fx.wrap` to ensure proper error handling and compatibility with lua-effect's invocation mechanisms. This is required for any function passed to `exports('name', fn)`. ```lua exports('getUser', fx.wrap(function(userId) assert(userId and userId > 0, 'Invalid user ID: ' .. tostring(userId)) return GetUser(userId) end)) ``` -------------------------------- ### Call a Local Function with lua-effect Source: https://github.com/itsnoxius/lua-effect/blob/main/docs/README.md Invoke a local function using `fx.invoke`. This function also returns a `Result` type, similar to calling remote exports. ```lua fx.invoke(fn, ...) ``` -------------------------------- ### fx.parseError Source: https://context7.com/itsnoxius/lua-effect/llms.txt Parses raw error strings into structured metadata, extracting file path, line number, resource name, and a clean message from FiveM-style error strings. It can also handle simple error messages without location information. ```APIDOC ## fx.parseError ### Description Parses a raw error string into structured metadata. Extracts file path, line number, resource name, and clean message from FiveM-style error strings. ### Method `fx.parseError(errorMessage: string) -> { message: string, location: string?, file: string?, line: number?, resource: string? }` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```lua -- Parse FiveM error format local parsed = fx.parseError('@example_resource/server.lua:42: Something went wrong') print(parsed.message) -- "Something went wrong" print(parsed.location) -- "@example_resource/server.lua:42" print(parsed.file) -- "@example_resource/server.lua" print(parsed.line) -- 42 print(parsed.resource) -- "example_resource" -- Handle various error formats local simple = fx.parseError('Simple error message') print(simple.message) -- "Simple error message" print(simple.line) -- nil (no location info) ``` ### Response #### Success Response (200) - **message** (string) - The cleaned error message. - **location** (string, optional) - The full location string (file:line). - **file** (string, optional) - The file path where the error occurred. - **line** (number, optional) - The line number where the error occurred. - **resource** (string, optional) - The resource name where the error occurred. #### Response Example ```json { "message": "Something went wrong", "location": "@example_resource/server.lua:42", "file": "@example_resource/server.lua", "line": 42, "resource": "example_resource" } ``` ```