View Issue Details

IDProjectCategoryView StatusLast Update
0002416Wishes.PluginsLuaMacro / Macro Browserpublic2017-10-23 17:04
ReporterJohnDoeAssigned To 
PrioritynormalSeverityminorReproducibilityN/A
Status newResolutionopen 
Product Version3.0 
Target VersionFixed in Version 
Summary0002416: Возможность вместо сообщений об ошибках вызывать "пользовательскую" lua-функцию
DescriptionЦель: детальный анализ ошибки
TagsNo tags attached.

Relationships

related to 0002387 new Wishes В диалоге об ошибке нужна возможность перейти к файлу 

Activities

JohnDoe

2014-02-08 23:58

updater   bugnote:0011825

Связанный тикет: 0002387

JohnDoe

2014-02-09 01:05

updater   bugnote:0011827

Если ошибка произошла при выполнении макроса, то желательно чтобы пользовательская функция получала аргумент thread

JohnDoe

2017-10-22 16:48

updater   bugnote:0015729

Пример реализации: http://forum.farmanager.com/viewtopic.php?p=146583#p146583

JohnDoe

2017-10-23 12:42

updater   bugnote:0015733

Last edited: 2017-10-23 17:04

View 6 revisions

Вторая итерация.
  1. Пользовательский обработчик берётся из export.CustomErrHandler, если там функция.
  2. Сигнатура функции предполагается аналогичной debug.traceback, т.е. CustomErrHandler ([thread,] [message [, level]])
  3. Если функция возвращает значение, то luamacro использует его в сообщении об ошибке. Если не возвращает, значит luamacro не отображает сообщений.

Изменения, требуемые в luamacro:

local function ErrHandler(...)              --new function
  if export.CustomErrHandler and type(export.CustomErrHandler)=="function" then
    local success, msg = xpcall(export.CustomErrHandler,debug.traceback,...)
    if success then return msg end
    ErrMsg(msg, "Error in CustomErrHandler")--todo localize
  end
  local msg = debug.traceback(...)
  if msg and type(msg)==string then
    return msg:gsub("\n\t","\n   ")
  else
    return msg
  end
end

local function FixReturn (handle, ok, ...)
  local ret1, ret_type = ...
  if ok then
    local status = co_status(handle.coro)
    if status == "suspended" and ret1 == PROPAGATE and ret_type ~= "exit" then
      handle._store = pack(select(3, ...))
      return ret_type, handle._store
    else
      return F.MPRT_NORMALFINISH, pack(true, ...)
    end
  else
    ret1 = ErrHandler(handle.coro, ret1)    --modified
    if ret1 then                            --modified
      ErrMsg(ret1)                          --modified
    end                                     --modified
    return F.MPRT_ERRORFINISH
  end
end

local function Init()
  Shared = {
    ErrHandler        = ErrHandler,         --added
-- ...

Описание изменений:
  1. Новая прокси-функция ErrHandler. Её задача: безопасно запустить пользовательский хэндлер, а если не удалось (или не задан), то вернуть обычный traceback.
  2. Желательно использовать пользовательский хэндлер во всех нужных местах, т.е. практически везде, где сейчас отображается traceback. Поэтому функция должна быть доступна вспомогательным скриптам плагина luamacro, для чего она и помещается в таблицу Shared.
  3. В FixReturn — пример использования. Аналогичные изменения предстоит внести и в другие места (utils.lua:713,746; luamacro.lua:294).

Сопутствующие модификации:
Замена начальных табов перенесена в ErrHandler, соответственно надо будет убрать копипасту из других мест (utils.lua:719,753).
Для debug.traceback то, что сообщение не является строкой - штатная ситуация, поэтому я не проверяю полученный аргумент.
Но необходимо убедиться, что "принимающая сторона" готова к этой ситуации, например "защитить" функцию ErrMsg:
local ErrMsg = function(msg, title, buttons, flags)
  if type(msg)~="string" then  --<--
    msg = tostring(msg)        --<--
  elseif not msg:utf8valid() then
    local wstr = win.MultiByteToWideChar(msg, win.GetACP(), "e")
    msg = wstr and win.Utf16ToUtf8(wstr) or msg
  end
  return far.Message(msg, title or "LuaMacro", buttons, flags or "wl")
end


P.S.
Кроме того, надо изучить места, где traceback сейчас вызывается не для корутины, а для функции в текущем контексте.
Чтобы исключить лишнюю информацию из стека, надо либо передавать level, либо обернуть функцию в корутину (полагаю так будет аккуратнее).

JohnDoe

2017-10-23 13:04

updater   bugnote:0015734

Если предложение принимается "в принципе", то для дальнейшего обсуждения подготовлю общий патч.

Issue History

Date Modified Username Field Change
2013-05-27 21:37 JohnDoe New Issue
2014-02-08 23:58 JohnDoe Note Added: 0011825
2014-02-09 01:05 JohnDoe Note Added: 0011827
2014-09-02 11:00 shmuel Relationship added related to 0002387
2017-10-22 16:48 JohnDoe Note Added: 0015729
2017-10-23 12:42 JohnDoe Note Added: 0015733
2017-10-23 12:49 JohnDoe Note Edited: 0015733 View Revisions
2017-10-23 13:01 JohnDoe Note Edited: 0015733 View Revisions
2017-10-23 13:04 JohnDoe Note Added: 0015734
2017-10-23 16:48 JohnDoe Note Edited: 0015733 View Revisions
2017-10-23 16:53 JohnDoe Note Edited: 0015733 View Revisions
2017-10-23 17:04 JohnDoe Note Edited: 0015733 View Revisions