# mlua 链接库函数错误处理

> [mlua 链接库函数错误处理](https://www.ftls.xyz/posts/2024-07-10-mlua-err/)
> Penned by [恐咖兵糖](https://www.ftls.xyz/) on 2024-07-10


mlua 链接库函数错误处理两种方法。

<!--more-->

## 环境

Lua 5.1.5

## 实践

### 思路

处理错误，第一种 pcall + os.exit ，第二中返回多个值判断不为 nil 然后 error(err) 退出。

### 代码

Cargo.toml

```toml
[package]
name = "myrslib"
version = "0.1.0"
edition = "2021"
authors = ["恐咖兵糖 <0@ftls.xyz>"]


[lib]
crate-type = ["cdylib"]

[dependencies]
mlua = { version = "0.9.9", features = ["lua51", "module"] }
```

src/hi.rs

```rs
use mlua::prelude::LuaResult;
use mlua::Lua;

pub fn hello(_: &Lua, name: String) -> LuaResult<()> {
    println!("hello, {}!", name);
    print!("hello, {}!", name);
    print!("{}", name);
    println!("hello, {}!", name);
    Ok(())
}

pub fn hi(_: &Lua, url: String) -> LuaResult<String> {
    if url.starts_with("http") {
        Ok(format!("Valid URL: {}", url))
    } else {
        Err(mlua::Error::external("Invalid URL"))
    }
}

pub fn hi2(lua: &Lua, _url: String) -> LuaResult<mlua::MultiValue> {
    let mut result = mlua::MultiValue::from_vec(vec![
        mlua::Value::String(lua.create_string("1str").unwrap()),
        mlua::Value::String(lua.create_string("2str").unwrap()),
    ]);

    result.push_front(mlua::Value::String(lua.create_string("3str").unwrap()));
    result.push_front(mlua::Nil);
    Ok(result)
}
```

src/lib.rs
```rs
mod hi;

use mlua::prelude::*;
use mlua::Lua;

// 定义 Lua
#[mlua::lua_module]
fn kkbt_rs_module(lua: &Lua) -> LuaResult<LuaTable> {
    let exports = lua.create_table()?;
    // hi.rs1
    exports.set("hello", lua.create_function(hi::hello)?)?;
    exports.set("hi", lua.create_function(hi::hi)?)?;
    exports.set("hi2", lua.create_function(hi::hi2)?)?;

    Ok(exports)
}

```

justfile 构建命令
```bash
dev:
    cargo build --release
    cp target/release/libmyrslib.so tests/kkbt_rs_module.so
    cd tests &&  lua test.lua
```

tests/test.lua

```lua
local mod = require("kkbt_rs_module")

print(mod.hello("kkbt"))

local result, err = pcall(mod.hi, "some")
if not result then print(err) end

print(mod.hi2("X"))
local x , y ,err = mod.hi2("x")
-- 类似 Go 错误处理 ， mlua::Error 需要 pcall 触发
-- if err then error(err) end
if err then error(err) end
```