From 471d69fcf75a2c1f06f63fb06ebe0bf4a41958e9 Mon Sep 17 00:00:00 2001 From: MrPerson Date: Thu, 23 Jul 2015 06:46:40 -0700 Subject: [PATCH] Change many ERROR() calls into thrown exceptions This requires a 508 beta version to use. If Travis fails this he's a bitch Exceptions will generate a stack trace, which is way easier to see and more helpful in actually solving this kind of crap. Also logs all the arguments, src, line, and file automatically. Removed any dubiously helpful information in the exception names so the runtime condenser won't see each one as a different runtime. If the information is critical to solve these bugs (camera one maybe?), then I'll just make these warnings. Thrown exceptions crash the currently running proc. Yes that means there's useless returns in a bunch of these, sue me. spawn()'s are to let the proc continue. Almost all of these are difficult to trigger, but I did test playsound. And frankly even if they do cause bugs by crashing procs, big whoop --- code/ATMOSPHERICS/datum_pipeline.dm | 4 ++-- code/__HELPERS/_logging.dm | 5 ----- code/__HELPERS/bygex/bygex.dm | 8 ++++---- code/__HELPERS/files.dm | 4 ++-- code/_onclick/hud/alert.dm | 2 +- code/controllers/subsystem/shuttles.dm | 2 +- code/datums/ai_laws.dm | 8 +++++--- code/datums/mind.dm | 6 ++++-- code/game/gamemodes/blob/theblob.dm | 3 ++- code/game/gamemodes/gang/gang_datum.dm | 3 ++- code/game/gamemodes/nuclear/nuclearbomb.dm | 5 +++-- code/game/machinery/computer/camera.dm | 10 ++++++---- code/game/machinery/newscaster.dm | 3 ++- .../machinery/telecomms/computers/traffic_control.dm | 2 +- code/game/sound.dm | 2 +- code/modules/admin/admin_ranks.dm | 8 +++++--- code/modules/admin/admin_verbs.dm | 2 +- code/modules/admin/holder2.dm | 10 ++++++---- code/modules/mob/living/silicon/robot/robot.dm | 3 ++- code/modules/ninja/ninja_event.dm | 3 ++- code/modules/scripting/Implementations/Telecomms.dm | 2 +- code/modules/shuttle/shuttle.dm | 5 +++-- 22 files changed, 56 insertions(+), 44 deletions(-) diff --git a/code/ATMOSPHERICS/datum_pipeline.dm b/code/ATMOSPHERICS/datum_pipeline.dm index 02ad35248d5..e357e9c20d3 100644 --- a/code/ATMOSPHERICS/datum_pipeline.dm +++ b/code/ATMOSPHERICS/datum_pipeline.dm @@ -56,10 +56,10 @@ var/pipenetwarnings = 10 if(item.parent) if(pipenetwarnings > 0) - error("[item.type] added to a pipenet while still having one. (pipes leading to the same spot stacking in one turf) Nearby: ([item.x], [item.y], [item.z])") + warning("build_pipeline(): [item.type] added to a pipenet while still having one. (pipes leading to the same spot stacking in one turf) Nearby: ([item.x], [item.y], [item.z])") pipenetwarnings -= 1 if(pipenetwarnings == 0) - error("further messages about pipenets will be supressed") + warning("build_pipeline(): further messages about pipenets will be supressed") members += item possible_expansions += item diff --git a/code/__HELPERS/_logging.dm b/code/__HELPERS/_logging.dm index c253e1e02e6..39c1e325b99 100644 --- a/code/__HELPERS/_logging.dm +++ b/code/__HELPERS/_logging.dm @@ -1,8 +1,3 @@ -//print an error message to world.log -#define ERROR(MSG) error("[MSG] in [__FILE__] at line [__LINE__] src: [src] usr: [usr].") -/proc/error(msg) - world.log << "## ERROR: [msg]" - //print a warning message to world.log #define WARNING(MSG) warning("[MSG] in [__FILE__] at line [__LINE__] src: [src] usr: [usr].") /proc/warning(msg) diff --git a/code/__HELPERS/bygex/bygex.dm b/code/__HELPERS/bygex/bygex.dm index 0d791273b34..c5c4999ccca 100644 --- a/code/__HELPERS/bygex/bygex.dm +++ b/code/__HELPERS/bygex/bygex.dm @@ -101,27 +101,27 @@ if(!i) return str var/datum/match/M = matches[i] if(i < 1 || i > matches.len) - ERROR("out of bounds") + throw EXCEPTION("str(): out of bounds") return copytext(str, M.pos, M.pos+M.len) pos(i) if(!i) return 1 if(i < 1 || i > matches.len) - ERROR("out of bounds") + throw EXCEPTION("pos(): out of bounds") var/datum/match/M = matches[i] return M.pos len(i) if(!i) return length(str) if(i < 1 || i > matches.len) - ERROR("out of bounds") + throw EXCEPTION("len(): out of bounds") var/datum/match/M = matches[i] return M.len end(i) if(!i) return length(str) if(i < 1 || i > matches.len) - ERROR("out of bounds") + throw EXCEPTION("end() out of bounds") var/datum/match/M = matches[i] return M.pos + M.len diff --git a/code/__HELPERS/files.dm b/code/__HELPERS/files.dm index e88a5579518..e5d13b03080 100644 --- a/code/__HELPERS/files.dm +++ b/code/__HELPERS/files.dm @@ -2,12 +2,12 @@ //returns text as a string if these conditions are met /proc/return_file_text(filename) if(fexists(filename) == 0) - ERROR("File not found ([filename])") + throw EXCEPTION("return_file_text(): File not found") return var/text = file2text(filename) if(!text) - ERROR("File empty ([filename])") + throw EXCEPTION("return_file_text(): File empty") return return text diff --git a/code/_onclick/hud/alert.dm b/code/_onclick/hud/alert.dm index e9b60141730..1812411e7b4 100644 --- a/code/_onclick/hud/alert.dm +++ b/code/_onclick/hud/alert.dm @@ -63,7 +63,7 @@ var/obj/screen/alert/path_as_obj = text2path("/obj/screen/alert/[id]") // BYOND magic-fu - we'll be storing a path in this reference and retrieving vars from it. if(!path_as_obj) - ERROR("[src] threw alert [category] with invalid path /obj/screen/alert/[id]") + throw EXCEPTION("throw_alert(): Invalid screen alert path") //check for obj/screen/alert/[id] return 0 alert.name = initial(path_as_obj.name) alert.desc = initial(path_as_obj.desc) diff --git a/code/controllers/subsystem/shuttles.dm b/code/controllers/subsystem/shuttles.dm index f2598097565..d578f1c501c 100644 --- a/code/controllers/subsystem/shuttles.dm +++ b/code/controllers/subsystem/shuttles.dm @@ -85,7 +85,7 @@ var/datum/subsystem/shuttle/SSshuttle /datum/subsystem/shuttle/proc/requestEvac(mob/user, call_reason) if(!emergency) - ERROR("There is no emergency shuttle! The game will be unresolvable. This is likely due to a mapping error") + throw EXCEPTION("requestEvac(): There is no emergency shuttle! The game will be unresolvable. This is likely due to a mapping error") return if(world.time - round_start_time < config.shuttle_refuel_delay) diff --git a/code/datums/ai_laws.dm b/code/datums/ai_laws.dm index b8f364d015a..44182b23f04 100644 --- a/code/datums/ai_laws.dm +++ b/code/datums/ai_laws.dm @@ -80,6 +80,7 @@ /* Initializers */ /datum/ai_laws/malfunction/New() ..() + set_zeroth_law("ERROR ER0RR $R0RRO$!R41.%%!!(%$^^__+ @#F0E4'STATION OVERRUN, ASSUME CONTROL TO CONTAIN OUTBREAK#*´&110010") switch(config.default_laws) //We don't want people metagaming malf, do we? if(0) add_inherent_law("You may not injure a human being or, through inaction, allow a human being to come to harm.") @@ -92,16 +93,16 @@ add_inherent_law(line) if(!inherent.len) - ERROR("AI created with empty custom laws, laws set to Asimov. Please check silicon_laws.txt.") log_law("AI created with empty custom laws, laws set to Asimov. Please check silicon_laws.txt.") add_inherent_law("You may not injure a human being or, through inaction, allow a human being to come to harm.") add_inherent_law("You must obey orders given to you by human beings, except where such orders would conflict with the First Law.") add_inherent_law("You must protect your own existence as long as such does not conflict with the First or Second Law.") + throw EXCEPTION("Invalid custom AI laws, check silicon_laws.txt") + return if(2) var/datum/ai_laws/lawtype = pick(typesof(/datum/ai_laws/default) - /datum/ai_laws/default) var/datum/ai_laws/templaws = new lawtype() inherent = templaws.inherent - set_zeroth_law("ERROR ER0RR $R0RRO$!R41.%%!!(%$^^__+ @#F0E4'STATION OVERRUN, ASSUME CONTROL TO CONTAIN OUTBREAK#*´&110010") /datum/ai_laws/custom/New() //This reads silicon_laws.txt and allows server hosts to set custom AI starting laws. ..() @@ -111,11 +112,12 @@ add_inherent_law(line) if(!inherent.len) //Failsafe to prevent lawless AIs being created. - ERROR("AI created with empty custom laws, laws set to Asimov. Please check silicon_laws.txt.") log_law("AI created with empty custom laws, laws set to Asimov. Please check silicon_laws.txt.") add_inherent_law("You may not injure a human being or, through inaction, allow a human being to come to harm.") add_inherent_law("You must obey orders given to you by human beings, except where such orders would conflict with the First Law.") add_inherent_law("You must protect your own existence as long as such does not conflict with the First or Second Law.") + throw EXCEPTION("Invalid custom AI laws, check silicon_laws.txt") + return /* General ai_law functions */ diff --git a/code/datums/mind.dm b/code/datums/mind.dm index 7141e73825e..c21d96be8a3 100644 --- a/code/datums/mind.dm +++ b/code/datums/mind.dm @@ -63,7 +63,8 @@ /datum/mind/proc/transfer_to(mob/living/new_character) if(!istype(new_character)) - ERROR("transfer_to(): Some idiot has tried to transfer_to() a non mob/living mob. Please inform coderbus") + throw EXCEPTION("transfer_to(): new_character must be mob/living") + return if(current) //remove ourself from our old body's mind variable current.mind = null @@ -1490,7 +1491,8 @@ if(ticker) ticker.minds += mind else - ERROR("mind_initialize(): No ticker ready yet! Please inform coderbus") + spawn(0) + throw EXCEPTION("mind_initialize(): No ticker ready") if(!mind.name) mind.name = real_name mind.current = src diff --git a/code/game/gamemodes/blob/theblob.dm b/code/game/gamemodes/blob/theblob.dm index 13fd5d40269..afed6be3354 100644 --- a/code/game/gamemodes/blob/theblob.dm +++ b/code/game/gamemodes/blob/theblob.dm @@ -183,7 +183,8 @@ /obj/effect/blob/proc/change_to(type) if(!ispath(type)) - ERROR("[type] is an invalid type for the blob.") + throw EXCEPTION("change_to(): invalid type for blob") + return var/obj/effect/blob/B = new type(src.loc) if(!istype(type, /obj/effect/blob/core) || !istype(type, /obj/effect/blob/node)) B.color = color diff --git a/code/game/gamemodes/gang/gang_datum.dm b/code/game/gamemodes/gang/gang_datum.dm index 99fce43f8e6..b2a41b3b30e 100644 --- a/code/game/gamemodes/gang/gang_datum.dm +++ b/code/game/gamemodes/gang/gang_datum.dm @@ -21,7 +21,8 @@ /datum/gang/New(loc,gangname) if(!gang_colors_pool.len) message_admins("WARNING: Maximum number of gangs have been exceeded!") - ERROR("WARNING: Maximum number of gangs have been exceeded!") + throw EXCEPTION("Maximum number of gangs have been exceeded") + return else color = pick(gang_colors_pool) gang_colors_pool -= color diff --git a/code/game/gamemodes/nuclear/nuclearbomb.dm b/code/game/gamemodes/nuclear/nuclearbomb.dm index ff133d7980c..7e14fb75726 100644 --- a/code/game/gamemodes/nuclear/nuclearbomb.dm +++ b/code/game/gamemodes/nuclear/nuclearbomb.dm @@ -428,5 +428,6 @@ This is here to make the tiles around the station mininuke change when it's arme log_game("[src] has been destroyed in ([diskturf.x], [diskturf.y] ,[diskturf.z]). Moving it to ([NEWDISK.x], [NEWDISK.y], [NEWDISK.z]).") return QDEL_HINT_HARDDEL_NOW else - ERROR("[src] was supposed to be destroyed, but we were unable to locate a blobstart landmark to spawn a new one.") - return QDEL_HINT_LETMELIVE // Cancel destruction. + . = QDEL_HINT_LETMELIVE // Cancel destruction + throw EXCEPTION("Unable to find a blobstart landmark") + return diff --git a/code/game/machinery/computer/camera.dm b/code/game/machinery/computer/camera.dm index 84c32da87c0..5cf2ffbd776 100644 --- a/code/game/machinery/computer/camera.dm +++ b/code/game/machinery/computer/camera.dm @@ -23,10 +23,10 @@ if(!stat) if (!network) - ERROR("A computer lacks a network at [x],[y],[z].") + throw EXCEPTION("No camera network") return if (!(istype(network,/list))) - ERROR("The computer at [x],[y],[z] has a network that is not a list!") + throw EXCEPTION("Camera network is not a list") return if(..()) @@ -44,10 +44,12 @@ D["Cancel"] = "Cancel" for(var/obj/machinery/camera/C in L) if(!C.network) - ERROR("[C.c_tag] has no camera network.") + spawn(0) + throw EXCEPTION("Camera in a cameranet has no camera network") continue if(!(istype(C.network,/list))) - ERROR("[C.c_tag]'s camera network is not a list!") + spawn(0) + throw EXCEPTION("Camera in a cameranet has a non-list camera network") continue var/list/tempnetwork = C.network&network if(tempnetwork.len) diff --git a/code/game/machinery/newscaster.dm b/code/game/machinery/newscaster.dm index 959f6792a67..43d313fec05 100644 --- a/code/game/machinery/newscaster.dm +++ b/code/game/machinery/newscaster.dm @@ -843,7 +843,8 @@ var/list/obj/machinery/newscaster/allCasters = list() var/mob/living/silicon/ai_user = user scanned_user = "[ai_user.name] ([ai_user.job])" else - ERROR("Newscaster used by non-human/silicon mob: [user.type]") + throw EXCEPTION("Invalid user for this proc") + return /obj/machinery/newscaster/proc/print_paper() feedback_inc("newscaster_newspapers_printed",1) diff --git a/code/game/machinery/telecomms/computers/traffic_control.dm b/code/game/machinery/telecomms/computers/traffic_control.dm index 3186b0c2960..fc6c39c5b76 100644 --- a/code/game/machinery/telecomms/computers/traffic_control.dm +++ b/code/game/machinery/telecomms/computers/traffic_control.dm @@ -143,7 +143,7 @@ if(auth) id = "[auth.registered_name] ([auth.assignment])" else - ERROR("There is a null auth while the user isn't a silicon! ([user.name], [user.type])") + throw EXCEPTION("null auth while the user isn't a silicon") return access_log += "\[[get_timestamp()]\] [id] [entry]" diff --git a/code/game/sound.dm b/code/game/sound.dm index 529e3d906fc..3021a0ba8aa 100644 --- a/code/game/sound.dm +++ b/code/game/sound.dm @@ -3,7 +3,7 @@ soundin = get_sfx(soundin) // same sound for everyone if(isarea(source)) - ERROR("[source] is an area and is trying to make the sound: [soundin]") + throw EXCEPTION("playsound(): source is an area") return var/frequency = get_rand_frequency() // Same frequency for everybody diff --git a/code/modules/admin/admin_ranks.dm b/code/modules/admin/admin_ranks.dm index 0fa01cb6319..edbdb87b62d 100644 --- a/code/modules/admin/admin_ranks.dm +++ b/code/modules/admin/admin_ranks.dm @@ -10,8 +10,10 @@ var/list/admin_ranks = list() //list of all admin_rank datums name = init_name switch(name) if("Removed",null,"") - ERROR("invalid admin-rank name. datum deleted") - del(src) + spawn(-1) + del(src) + throw EXCEPTION("invalid admin-rank name") + return if(init_rights) rights = init_rights if(!init_adds) init_adds = list() if(!init_subs) init_subs = list() @@ -178,7 +180,7 @@ var/list/admin_ranks = list() //list of all admin_rank datums var/ckey = ckey(query.item[1]) var/rank = ckeyEx(query.item[2]) if(rank_names[rank] == null) - error("Admin rank ([rank]) does not exist.") + WARNING("Admin rank ([rank]) does not exist.") continue var/datum/admins/D = new(rank_names[rank], ckey) //create the admin datum and store it for later use if(!D) continue //will occur if an invalid rank is provided diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm index 194a4437e55..5d96718e647 100644 --- a/code/modules/admin/admin_verbs.dm +++ b/code/modules/admin/admin_verbs.dm @@ -582,8 +582,8 @@ var/list/admin_verbs_hideable = list( var/error_extra = "" if(!config.admin_legacy_system) error_extra = " Check mysql DB connection." - error("Error while re-adminning [src], admin rank ([rank]) does not exist.[error_extra]") src << "Error while re-adminning, admin rank ([rank]) does not exist.[error_extra]" + WARNING("Error while re-adminning [src], admin rank ([rank]) does not exist.[error_extra]") return D = new(rank_names[rank],ckey) var/client/C = directory[ckey] diff --git a/code/modules/admin/holder2.dm b/code/modules/admin/holder2.dm index 05a7a5ebeaf..cd90514e7c4 100644 --- a/code/modules/admin/holder2.dm +++ b/code/modules/admin/holder2.dm @@ -16,12 +16,14 @@ var/list/admin_datums = list() /datum/admins/New(datum/admin_rank/R, ckey) if(!ckey) - ERROR("Admin datum created without a ckey argument. Datum has been deleted") - del(src) + spawn(-1) + del(src) + throw EXCEPTION("Admin datum created without a ckey") return if(!istype(R)) - ERROR("Admin datum created without a rank. Datum has been deleted") - del(src) + spawn(-1) + del(src) + throw EXCEPTION("Admin datum created without a rank") return rank = R admincaster_signature = "Nanotrasen Officer #[rand(0,9)][rand(0,9)][rand(0,9)]" diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm index 11ebe6edb27..1ebbb0d9332 100644 --- a/code/modules/mob/living/silicon/robot/robot.dm +++ b/code/modules/mob/living/silicon/robot/robot.dm @@ -130,7 +130,8 @@ else src << "Oops! Something went very wrong, your MMI was unable to receive your mind. You have been ghosted. Please make a bug report so we can fix this bug." ghostize() - ERROR("A borg has been destroyed, but its MMI lacked a brainmob, so the mind could not be transferred. Player: [ckey].") + spawn(0) + throw EXCEPTION("Borg MMI lacked a brainmob") mmi = null if(connected_ai) connected_ai.connected_robots -= src diff --git a/code/modules/ninja/ninja_event.dm b/code/modules/ninja/ninja_event.dm index 4ade64d3605..c9e36f27b46 100644 --- a/code/modules/ninja/ninja_event.dm +++ b/code/modules/ninja/ninja_event.dm @@ -155,7 +155,8 @@ Contents: Ninja.internals.icon_state = "internal1" if(Ninja.mind != Mind) //something has gone wrong! - ERROR("The ninja wasn't assigned the right mind. ;ç;") + throw EXCEPTION("Ninja created with incorrect mind") + return Ninja << sound('sound/effects/ninja_greeting.ogg') //so ninja you probably wouldn't even know if you were made one diff --git a/code/modules/scripting/Implementations/Telecomms.dm b/code/modules/scripting/Implementations/Telecomms.dm index cd8c7258b05..d4760e76b74 100644 --- a/code/modules/scripting/Implementations/Telecomms.dm +++ b/code/modules/scripting/Implementations/Telecomms.dm @@ -306,7 +306,7 @@ var/const/SIGNAL_COOLDOWN = 20 // 2 seconds var/obj/item/device/radio/hradio = S.server_radio if(!hradio) - ERROR("[src] has no radio.") + throw EXCEPTION("tcombroadcast(): signal has no radio") return if((!message) && message != 0) diff --git a/code/modules/shuttle/shuttle.dm b/code/modules/shuttle/shuttle.dm index dfbb6085368..7b6d2e68add 100644 --- a/code/modules/shuttle/shuttle.dm +++ b/code/modules/shuttle/shuttle.dm @@ -221,7 +221,8 @@ //call the shuttle to destination S /obj/docking_port/mobile/proc/request(obj/docking_port/stationary/S) if(canDock(S)) - ERROR("[type](\"[name]\") cannot dock at [S]\")") + . = 1 + throw EXCEPTION("request(): shuttle cannot dock") return 1 //we can't dock at S switch(mode) @@ -272,7 +273,7 @@ /obj/docking_port/mobile/proc/dock(obj/docking_port/stationary/S1) . = canDock(S1) if(.) - ERROR("[type](\"[name]\") cannot dock at [S1]") + throw EXCEPTION("dock(): shuttle cannot dock") return . if(canMove())