/
githubmirror
/
vgstation13
Обзор
Документация
Войти
/
githubmirror
/
vgstation13
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
Bleeding-Edge
code/modules/error_handler/error_handler.dm
118 строк
4 KB
DamianX
Compile-time options for development (#20119)
17 окт 2018, 14:07
17 окт 2018, 14:07
b8a592d
Код
Авторство
О чём код?
/var/list/error_last_seen = list() // error_cooldown items will either be positive (cooldown time) or negative (silenced error) // If negative, starts at -1, and goes down by 1 each time that error gets skipped /var/list/error_cooldown = list() /var/total_runtimes = 0 /var/total_runtimes_skipped = 0 // The ifdef needs to be down here, since the error viewer references total_runtimes #ifdef DEBUG /world/Error(var/exception/e) if (!istype(e)) // Something threw an unusual exception world.log << "\[[time_stamp()]] Uncaught exception: [e]" return ..() if (!global.error_last_seen) // A runtime is occurring too early in start-up initialization return ..() global.total_runtimes++ var/erroruid = "[e.file][e.line]:[e]" var/last_seen = global.error_last_seen[erroruid] var/cooldown = global.error_cooldown[erroruid] || 0 if (last_seen == null) // A new error! global.error_last_seen[erroruid] = world.time last_seen = world.time if (cooldown < 0) global.error_cooldown[erroruid]-- // Used to keep track of skip count for this error global.total_runtimes_skipped++ return // Error is currently silenced, skip handling it // Handle cooldowns and silencing spammy errors var/silencing = 0 // We can runtime before config is initialized because BYOND initialize objs/map before a bunch of other stuff happens. // This is a bunch of workaround code for that. Hooray! var/configured_error_cooldown var/configured_error_limit var/configured_error_silence_time if(config) configured_error_cooldown = config.error_cooldown configured_error_limit = config.error_limit configured_error_silence_time = config.error_silence_time else configured_error_cooldown = initial(config.error_cooldown) configured_error_limit = initial(config.error_limit) configured_error_silence_time = initial(config.error_silence_time) // Each occurrence of a unique error adds to its "cooldown" time... cooldown = max(0, cooldown - (world.time - last_seen)) + configured_error_cooldown // ... which is used to silence an error if it occurs too often, too fast if (cooldown > configured_error_cooldown * configured_error_limit) cooldown = -1 silencing = 1 spawn (0) usr = null sleep(configured_error_silence_time) var/skipcount = abs(global.error_cooldown[erroruid]) - 1 global.error_cooldown[erroruid] = 0 if (skipcount > 0) world.log << "\[[time_stamp()]] Skipped [skipcount] runtimes in [e.file],[e.line]: [e]" error_cache.log_error(e, skip_count = skipcount) global.error_last_seen[erroruid] = world.time global.error_cooldown[erroruid] = cooldown // The detailed error info needs some tweaking to make it look nice var/list/usrinfo = null var/locinfo if (istype(usr)) usrinfo = list(" usr: [datum_info_line(usr)]") locinfo = atom_loc_line(usr) if (locinfo) usrinfo += " usr.loc: [locinfo]" // The proceeding mess will almost definitely break if error messages are ever changed // I apologize in advance var/list/splitlines = splittext(e.desc, "\n") var/list/desclines = list() if (splitlines.len > ERROR_USEFUL_LEN) // If there aren't at least three lines, there's no info for (var/line in splitlines) if (length(line) < 3 || findtext(line, "source file:") || findtext(line, "usr.loc:")) continue if (findtext(line, "usr:")) if (usrinfo) desclines.Add(usrinfo) usrinfo = null continue // Our usr info is better, replace it if (copytext(line, 1, 3) != " ") desclines += (" " + line) // Pad any unpadded lines, so they look pretty else desclines += line if (usrinfo) // If this isn't null, it hasn't been added yet desclines.Add(usrinfo) if (silencing) desclines += " (This error will now be silenced for [configured_error_silence_time / 600] minutes)" // Now to actually output the error info... var/main_line = "\[[time_stamp()]] Runtime in [e.file],[e.line]: [e]" world.log << main_line for (var/line in desclines) world.log << line if (global.error_cache) global.error_cache.log_error(e, desclines) #if UNIT_TESTS_ENABLED if(global.current_test) global.current_test.fail("[main_line]\n[desclines.Join("\n")]") #endif #endif