Skip to content

Commit 768ccda

Browse files
authored
Merge pull request #1142 from mmd-osm/patch/issue_1136
Provide a stack trace on a lua error with flex backend
2 parents 5caa410 + 8c50415 commit 768ccda

File tree

3 files changed

+34
-1
lines changed

3 files changed

+34
-1
lines changed

src/lua-utils.cpp

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,3 +135,34 @@ bool luaX_get_table_bool(lua_State *lua_state, char const *key, int table_index,
135135
throw std::runtime_error{
136136
"{} must contain a '{}' boolean field"_format(error_msg, key)};
137137
}
138+
139+
static int pcall_error_traceback_handler(lua_State *lua_state)
140+
{
141+
assert(lua_state);
142+
143+
char const *msg = lua_tostring(lua_state, 1);
144+
if (msg == nullptr) { // is error object not a string?
145+
if (luaL_callmeta(lua_state, 1,
146+
"__tostring") && // does it have a metamethod
147+
lua_type(lua_state, -1) == LUA_TSTRING) { // that produces a string?
148+
return 1; // that is the message
149+
} else {
150+
msg = lua_pushfstring(lua_state, "(error object is a %s value)",
151+
luaL_typename(lua_state, 1));
152+
}
153+
}
154+
luaL_traceback(lua_state, lua_state, msg, 1); // append a standard traceback
155+
return 1; // return the traceback
156+
}
157+
158+
// wrapper function for lua_pcall to include a stack traceback
159+
int luaX_pcall(lua_State *lua_state, int narg, int nres)
160+
{
161+
int const base = lua_gettop(lua_state) - narg; // function index
162+
lua_pushcfunction(lua_state,
163+
pcall_error_traceback_handler); // push message handler
164+
lua_insert(lua_state, base); // put it under function and args
165+
int const status = lua_pcall(lua_state, narg, nres, base);
166+
lua_remove(lua_state, base); // remove message handler from the stack
167+
return status;
168+
}

src/lua-utils.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,4 +49,6 @@ char const *luaX_get_table_string(lua_State *lua_state, char const *key,
4949
bool luaX_get_table_bool(lua_State *lua_state, char const *key, int table_index,
5050
char const *error_msg, bool default_value);
5151

52+
int luaX_pcall(lua_State *lua_state, int narg, int nres);
53+
5254
#endif // OSM2PGSQL_FLEX_LUA_HPP

src/output-flex.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -996,7 +996,7 @@ void output_flex_t::call_process_function(int index,
996996
get_options()->extra_attributes); // the single argument
997997

998998
luaX_set_context(lua_state(), this);
999-
if (lua_pcall(lua_state(), 1, 0, 0)) {
999+
if (luaX_pcall(lua_state(), 1, 0)) {
10001000
throw std::runtime_error{"Failed to execute lua processing function:"
10011001
" {}"_format(lua_tostring(lua_state(), -1))};
10021002
}

0 commit comments

Comments
 (0)