I happened to retrieve a page name from a wiki URL, grabbed the title, but got a crash with
mw.title.lua:354: attempt to index local 'b' (a nil value)
Current situation
Step to reproduce
Enter this in a Lua inspection field:
=mw.title.makeTitle( "Project", "M%C3%BCnchen" )
Expected result
"Project:München"
or a mw.title object in code.
Current result
nil
No title object.
Follow-up error
Passing the supposed mw.title object to mw.title.equals() this crashes with the less informative message
mw.title.lua:354: attempt to index local 'b' (a nil value)
It left me a bit confused.
What should happen?
- Different from PHP, Lua code could be gracious if page titles do contain UTF-8 encoding. Within wikitext, [[M%C3%BCnchen]] works fine.
- If mw.title.equals() or others are called with invalid parameters, an informative message should appear rather than system fallback. local function checkNamespace() is fine.
Possible solutions
For mw.title library, rELUA /includes/Engines/LuaCommon/lualib/mw.title.lua
Permit UTF-8 encoding
In checkNamespace()
local ns = mw.site.namespaces[ mw.uri.decode( arg ) ]
Alternatively, mw.site library might accept UTF-8 encoded namespaces.
function title.makeTitle( ns, title, fragment, interwiki ) if type( title ) == 'string' then ns = checkNamespace( 'mw.title.makeTitle', 1, ns ) title = mw.uri.decode( title ) return makeTitleObject( php.makeTitle( ns, title, fragment, interwiki ) ) else local msg = "bad argument 'title' to 'mw.title.makeTitle'" error( msg, 3 ) end end
equals() error message
function title.equals( a, b ) if type( a ) == 'table' and type( b ) == 'table' then return a.interwiki == b.interwiki and a.namespace == b.namespace and a.text == b.text else local msg = "bad argument to 'mw.title.equals'" error( msg, 3 ) end end
compare() error message
function title.compare( a, b ) if type( a ) == 'table' and type( b ) == 'table' then if a.interwiki ~= b.interwiki then return a.interwiki < b.interwiki and -1 or 1 end if a.namespace ~= b.namespace then return a.namespace < b.namespace and -1 or 1 end if a.text ~= b.text then return a.text < b.text and -1 or 1 end return 0 else local msg = "bad argument to 'mw.title.compare'" error( msg, 3 ) end end
More precise location
Add library prefix to message, since at least equals() and compare() might occur in any object.
ns = checkNamespace( 'mw.title.inNamespace', 1, ns ) ns = checkNamespace( 'mw.title.inNamespaces', i, select( i, ... ) ) ns = checkNamespace( 'mw.title.hasSubjectNamespace', 1, ns )
Or within checkNamespace() itself.