Lapis
區分兩種錯誤:可恢復和不可恢復錯誤。 Lua
的運行時在執行期間拋出的錯誤或調用錯誤被認爲是不可恢復的。 (這也包括 Lua
內置函數 assert
)數據庫
由於不可恢復的錯誤不會被用戶捕獲,因此 Lapis
捕獲它們並向瀏覽器打印一個異常消息。任何已經運行的操做均可能會被停止,Lapis
將打印一個特殊視圖來顯示堆棧以及將 status
設置爲 500
。json
這些類型的錯誤一般是一個 bug
或其餘嚴重的問題,而且應該被修復。api
可恢復的錯誤是用戶控制停止執行一個處理函數以運行指定錯誤處理函數的方式。它們使用協程而不是 Lua
的錯誤系統來實現。數組
好比來自用戶的無效輸入或數據庫中缺乏的記錄。瀏覽器
capture_errors
幫助程序用於包裝一個操做,以便它能夠捕獲錯誤並運行錯誤處理程序。app
它不捕獲運行時錯誤。若是你想捕獲運行時錯誤,你應該使用 pcall
,就像你一般在 Lua
中作的那樣。函數
Lua
沒有大多數其餘語言的異常概念。相反,Lapis
使用協同程序建立一個異常處理系統。咱們使用 capture_errors
幫助程序來定義咱們必須捕獲錯誤的範圍。而後咱們可使用 yield_error
來拋出一個原始錯誤。ui
local lapis = require("lapis") local app_helpers = require("lapis.application") local capture_errors, yield_error = app_helpers.capture_errors, app_helpers.yield_error local app = lapis.Application() app:match("/do_something", capture_errors(function(self) yield_error("something bad happened") return "Hello!" end))
當出現錯誤時會發生什麼?該操做將在第一個錯誤處中止執行,而後運行錯誤處理程序。默認錯誤處理程序將在 self.errors
中設置一個相似數組的表,並返回 {render = true}
。在您的視圖中,您能夠顯示這些錯誤消息。這意味着若是你有一個命名的路由,那個路由的視圖將會被渲染。而後當出現一個 error
表時你應該編寫你本身的視圖。lua
若是你想有一個自定義的錯誤處理程序,你能夠傳入一個 table
來調用capture_errors
:(注意 self.errors
在自定義處理程序以前設置)code
app:match("/do_something", capture_errors({ on_error = function(self) log_erorrs(self.errors) -- you would supply the log_errors function return { render = "my_error_page", status = 500 } end, function(self) if self.params.bad_thing then yield_error("something bad happened") end return { render = true } end }))
當調用 capture_errors
處理函數時將使用傳入的 table
的第一個位置值做爲操做。
若是您正在構建 JSON API
,lapis
則會提供另外一個方法capture_errors_json
,它會在 JSON
對象中呈現錯誤,以下所示:
local lapis = require("lapis") local app_helpers = require("lapis.application") local capture_errors_json, yield_error = app_helpers.capture_errors_json, app_helpers.yield_error local app = lapis.Application() app:match("/", capture_errors_json(function(self) yield_error("something bad happened") end))
而後將呈現以下錯誤(請使用正確的content-type
)
{ errors: ["something bad happened"] }
assert_error
在 lua
中,當一個函數執行失敗時,習慣返回 nil
和一個錯誤消息。爲此,提供了一個 assert_error
幫助程序。若是第一個參數是 falsey
( nil
或 false
),那麼第二個參數做爲一個錯誤被拋出,不然全部的參數都會從函數返回。
使用 assert_error
對於數據庫的方法很是方便。
local lapis = require("lapis") local app_helpers = require("lapis.application") local capture_errors, assert_error = app_helpers.capture_errors, app_helpers.assert_error local app = lapis.Application() app:match("/", capture_errors(function(self) local user = assert_error(Users:find({id = "leafo"})) return "result: " .. user.id end))