diff --git a/code/controllers/ProcessScheduler/core/process.dm b/code/controllers/ProcessScheduler/core/process.dm index 836d2124bd..2d5b8b1b7d 100644 --- a/code/controllers/ProcessScheduler/core/process.dm +++ b/code/controllers/ProcessScheduler/core/process.dm @@ -327,9 +327,7 @@ /datum/controller/process/proc/catchException(var/exception/e, var/thrower) if(istype(e)) // Real runtimes go to the real error handler - // There are two newlines here, because handling desc sucks - e.desc = " Caught by process: [name]\n\n" + e.desc - world.Error(e, e_src = thrower) + log_runtime(e, thrower, "Caught by process: [name]") return var/etext = "[e]" var/eid = "[e]" // Exception ID, for tracking repeated exceptions diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm index 335241d15e..eaadf431bc 100644 --- a/code/modules/admin/topic.dm +++ b/code/modules/admin/topic.dm @@ -1176,6 +1176,18 @@ sleep(2) C.jumptomob(M) + else if(href_list["adminplayerobservefollow"]) + if(!check_rights(R_MENTOR|R_MOD|R_ADMIN|R_SERVER)) + return + + var/mob/M = locate(href_list["adminplayerobservefollow"]) + + var/client/C = usr.client + if(!isobserver(usr)) C.admin_ghost() + var/mob/observer/dead/G = C.mob + sleep(2) + G.ManualFollow(M) + else if(href_list["check_antagonist"]) check_antagonists() diff --git a/code/modules/error_handler/error_handler.dm b/code/modules/error_handler/error_handler.dm index 51fabd76fe..de71bfc1ca 100644 --- a/code/modules/error_handler/error_handler.dm +++ b/code/modules/error_handler/error_handler.dm @@ -8,7 +8,7 @@ var/total_runtimes_skipped = 0 #ifdef DEBUG /world/Error(var/exception/e, var/datum/e_src) if(!istype(e)) // Something threw an unusual exception - log_to_dd("\[[time2text(world.timeofday, "hh:mm")]] Uncaught exception: [e]") + log_to_dd("\[[time_stamp()]] Uncaught exception: [e]") return ..() if(!error_last_seen) // A runtime is occurring too early in start-up initialization return ..() @@ -39,7 +39,7 @@ var/total_runtimes_skipped = 0 var/skipcount = abs(error_cooldown[erroruid]) - 1 error_cooldown[erroruid] = 0 if(skipcount > 0) - log_to_dd("\[[time2text(world.timeofday, "hh:mm")]] Skipped [skipcount] runtimes in [e.file],[e.line].") + log_to_dd("\[[time_stamp()]] Skipped [skipcount] runtimes in [e.file],[e.line].") error_cache.logError(e, skipCount = skipcount) error_last_seen[erroruid] = world.time error_cooldown[erroruid] = cooldown @@ -95,10 +95,24 @@ var/total_runtimes_skipped = 0 desclines += " (This error will now be silenced for [ERROR_SILENCE_TIME / 600] minutes)" // Now to actually output the error info... - log_to_dd("\[[time2text(world.timeofday, "hh:mm")]] Runtime in [e.file],[e.line]: [e]") + log_to_dd("\[[time_stamp()]] Runtime in [e.file],[e.line]: [e]") for(var/line in desclines) log_to_dd(line) if(error_cache) error_cache.logError(e, desclines, e_src = e_src) #endif + +/proc/log_runtime(exception/e, datum/e_src, extra_info) + if(!istype(e)) + world.Error(e, e_src) + return + + if(extra_info) + // Adding extra info adds two newlines, because parsing runtimes is funky + if(islist(extra_info)) + e.desc = " [jointext(extra_info, "\n ")]\n\n" + e.desc + else + e.desc = " [extra_info]\n\n" + e.desc + + world.Error(e, e_src) diff --git a/code/modules/error_handler/error_viewer.dm b/code/modules/error_handler/error_viewer.dm index 9bbab68b63..0f1fd0ba96 100644 --- a/code/modules/error_handler/error_viewer.dm +++ b/code/modules/error_handler/error_viewer.dm @@ -14,7 +14,7 @@ var/global/datum/ErrorViewer/ErrorCache/error_cache = new() var/global/datum/ErrorViewer/ErrorCache/error_cache = null #endif -// - ErrorSource datums exist for each line (of code) that generates an error, +// - ErrorSource datums exist for each line (of code) that generates an error, // and keep track of all errors generated by that line. // // - ErrorEntry datums exist for each logged error, and keep track of all @@ -71,7 +71,15 @@ var/global/datum/ErrorViewer/ErrorCache/error_cache = null back_to_param = ";viewruntime_backto=\ref[back_to]" if(linear) back_to_param += ";viewruntime_linear=1" - return "[html_encode(linktext)]" + return "[html_encode(linktext)]" + +/datum/ErrorViewer/Topic(href, href_list) + if(..()) + return 1 + if(href_list["viewruntime_backto"]) + showTo(usr, locate(href_list["viewruntime_backto"]), href_list["viewruntime_linear"]) + else + showTo(usr, null, href_list["viewruntime_linear"]) /datum/ErrorViewer/ErrorCache var/list/errors = list()