Merge branch 'errorhandling' of git://github.com/mizipzor/dfhack

develop
Petr Mrázek 2010-02-28 04:26:10 +01:00
commit 029f1a6cf8
6 changed files with 265 additions and 195 deletions

@ -9,20 +9,32 @@
using namespace std; using namespace std;
#include <DFTypes.h> #include <DFTypes.h>
#include <DFHackAPI.h> #include <DFHackAPI.h>
#include <DFError.h>
int main (void) int main (void)
{ {
time_t start, end; time_t start, end;
double time_diff; double time_diff;
DFHack::API DF("Memory.xml"); DFHack::API DF("Memory.xml");
if(!DF.Attach()) //if(!DF.Attach())
//{
// cerr << "DF not found" << endl;
// return 1;
//}
//if(!DF.Detach())
//{
// cerr << "Can't detach from DF" << endl;
// return 1;
//}
try
{ {
cerr << "DF not found" << endl; DF.Attach();
return 1; DF.Detach();
} }
if(!DF.Detach()) catch (DFHack::Error::NoProcess& e)
{ {
cerr << "Can't detach from DF" << endl; cerr << e.what() << endl;
return 1; return 1;
} }

@ -2,6 +2,7 @@
SET(PROJECT_HDRS SET(PROJECT_HDRS
DFCommonInternal.h DFCommonInternal.h
DFError.h
DFHackAPI.h DFHackAPI.h
DFMemInfo.h DFMemInfo.h
DFMemInfoManager.h DFMemInfoManager.h

@ -85,6 +85,7 @@ namespace DFHack
#include "DFMemInfoManager.h" #include "DFMemInfoManager.h"
#include "DFVector.h" #include "DFVector.h"
#include "DFMemInfo.h" #include "DFMemInfo.h"
#include "DFError.h"
#include <stdlib.h> #include <stdlib.h>
#include "tinyxml/tinyxml.h" #include "tinyxml/tinyxml.h"

@ -0,0 +1,114 @@
/*
www.sourceforge.net/projects/dfhack
Copyright (c) 2009 Petr Mrázek (peterix), Kenneth Ferland (Impaler[WrG]), dorf
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any
damages arising from the use of this software.
Permission is granted to anyone to use this software for any
purpose, including commercial applications, and to alter it and
redistribute it freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must
not claim that you wrote the original software. If you use this
software in a product, an acknowledgment in the product documentation
would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and
must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution.
*/
#ifndef ERROR_H_INCLUDED
#define ERROR_H_INCLUDED
#include <string>
#include <sstream>
#include <exception>
namespace DFHack
{
namespace Error
{
class NoProcess : public exception
{
public:
virtual const char* what() const throw()
{
return "couldn't find a suitable process";
}
};
class CantAttach : public exception
{
public:
virtual const char* what() const throw()
{
return "couldn't attach to process";
}
};
class NoMapLoaded : public exception
{
public:
virtual const char* what() const throw()
{
return "no map has been loaded in the dwarf fortress process";
}
};
class BadMapDimensions : public exception
{
public:
BadMapDimensions(uint32_t& _x, uint32_t& _y) : x(_x), y(_y) {}
const uint32_t x;
const uint32_t y;
virtual const char* what() const throw()
{
return "both x and y needs to be between 0 and 48";
}
};
// a call to DFHack::mem_info::get* failed
class MissingMemoryDefinition : public exception
{
public:
MissingMemoryDefinition(const char* _type, const char* _key) : type(_type), key(_key) {}
// Used by functios using integer keys, such as getTrait
MissingMemoryDefinition(const char* _type, uint32_t _key) : type(_type)
{
// FIXME fancy hex printer goes here
std::stringstream s;
s << _key;
key = s.str();
}
// (perhaps it should be an enum, but this is intended for easy printing/logging)
// type can be any of the following:
//
// address
// offset
// hexvalue
// string
// profession
// job
// skill
// trait
// traitname
// labor
const std::string type;
std::string key;
virtual const char* what() const throw()
{
return "memory definition missing";
}
};
}
}
#endif // ERROR_H_INCLUDED

@ -187,8 +187,9 @@ bool API::InitMap()
//FIXME: very inadequate //FIXME: very inadequate
if (!x_array_loc) if (!x_array_loc)
{ {
throw Error::NoMapLoaded();
// bad stuffz happend // bad stuffz happend
return false; //return false;
} }
uint32_t mx, my, mz; uint32_t mx, my, mz;
@ -200,7 +201,8 @@ bool API::InitMap()
// test for wrong map dimensions // test for wrong map dimensions
if (mx == 0 || mx > 48 || my == 0 || my > 48 || mz == 0) if (mx == 0 || mx > 48 || my == 0 || my > 48 || mz == 0)
{ {
return false; throw Error::BadMapDimensions(mx, my);
//return false;
} }
// alloc array for pointers to all blocks // alloc array for pointers to all blocks
@ -656,19 +658,6 @@ bool API::ReadGeology (vector < vector <uint16_t> >& assign)
uint32_t regionX, regionY, regionZ; uint32_t regionX, regionY, regionZ;
uint16_t worldSizeX, worldSizeY; uint16_t worldSizeX, worldSizeY;
// check if we have 'em all
if (
! (
region_x_offset && region_y_offset && region_z_offset && world_size_x && world_size_y
&& world_offset && world_regions_offset && world_geoblocks_offset && region_size
&& region_geo_index_offset && geolayer_geoblock_offset
)
)
{
// fail if we don't have them
return false;
}
// read position of the region inside DF world // read position of the region inside DF world
g_pProcess->readDWord (region_x_offset, regionX); g_pProcess->readDWord (region_x_offset, regionX);
g_pProcess->readDWord (region_y_offset, regionY); g_pProcess->readDWord (region_y_offset, regionY);
@ -737,19 +726,10 @@ bool API::ReadGeology (vector < vector <uint16_t> >& assign)
bool API::InitReadBuildings ( uint32_t& numbuildings ) bool API::InitReadBuildings ( uint32_t& numbuildings )
{ {
int buildings = d->offset_descriptor->getAddress ("buildings"); int buildings = d->offset_descriptor->getAddress ("buildings");
if(buildings)
{
d->buildingsInited = true; d->buildingsInited = true;
d->p_bld = new DfVector (d->p->readVector (buildings, 4)); d->p_bld = new DfVector (d->p->readVector (buildings, 4));
numbuildings = d->p_bld->getSize(); numbuildings = d->p_bld->getSize();
return true; return true;
}
else
{
d->buildingsInited = false;
numbuildings = 0;
return false;
}
} }
@ -800,19 +780,10 @@ void API::FinishReadBuildings()
bool API::InitReadConstructions(uint32_t & numconstructions) bool API::InitReadConstructions(uint32_t & numconstructions)
{ {
int constructions = d->offset_descriptor->getAddress ("constructions"); int constructions = d->offset_descriptor->getAddress ("constructions");
if(constructions)
{
d->p_cons = new DfVector (d->p->readVector (constructions, 4)); d->p_cons = new DfVector (d->p->readVector (constructions, 4));
d->constructionsInited = true; d->constructionsInited = true;
numconstructions = d->p_cons->getSize(); numconstructions = d->p_cons->getSize();
return true; return true;
}
else
{
d->constructionsInited = false;
numconstructions = 0;
return false;
}
} }
@ -850,20 +821,21 @@ void API::FinishReadConstructions()
bool API::InitReadVegetation(uint32_t & numplants) bool API::InitReadVegetation(uint32_t & numplants)
{ {
try
{
int vegetation = d->offset_descriptor->getAddress ("vegetation"); int vegetation = d->offset_descriptor->getAddress ("vegetation");
d->tree_offset = d->offset_descriptor->getOffset ("tree_desc_offset"); d->tree_offset = d->offset_descriptor->getOffset ("tree_desc_offset");
if(vegetation && d->tree_offset)
{
d->vegetationInited = true; d->vegetationInited = true;
d->p_veg = new DfVector (d->p->readVector (vegetation, 4)); d->p_veg = new DfVector (d->p->readVector (vegetation, 4));
numplants = d->p_veg->getSize(); numplants = d->p_veg->getSize();
return true; return true;
} }
else catch (Error::MissingMemoryDefinition&)
{ {
d->vegetationInited = false; d->vegetationInited = false;
numplants = 0; numplants = 0;
return false; throw;
} }
} }
@ -895,6 +867,8 @@ void API::FinishReadVegetation()
bool API::InitReadCreatures( uint32_t &numcreatures ) bool API::InitReadCreatures( uint32_t &numcreatures )
{ {
try
{
memory_info * minfo = d->offset_descriptor; memory_info * minfo = d->offset_descriptor;
int creatures = d->offset_descriptor->getAddress ("creatures"); int creatures = d->offset_descriptor->getAddress ("creatures");
d->creature_pos_offset = minfo->getOffset ("creature_position"); d->creature_pos_offset = minfo->getOffset ("creature_position");
@ -921,45 +895,24 @@ bool API::InitReadCreatures( uint32_t &numcreatures )
d->creature_happiness_offset = minfo->getOffset ("creature_happiness"); d->creature_happiness_offset = minfo->getOffset ("creature_happiness");
d->creature_traits_offset = minfo->getOffset ("creature_traits"); d->creature_traits_offset = minfo->getOffset ("creature_traits");
d->creature_likes_offset = minfo->getOffset("creature_likes"); d->creature_likes_offset = minfo->getOffset("creature_likes");
if (creatures
&& d->creature_pos_offset
&& d->creature_type_offset
&& d->creature_flags1_offset
&& d->creature_flags2_offset
&& d->creature_nick_name_offset
&& d->creature_custom_profession_offset
&& d->creature_profession_offset
&& d->creature_sex_offset
&& d->creature_id_offset
&& d->creature_squad_name_offset
&& d->creature_squad_leader_id_offset
&& d->creature_money_offset
&& d->creature_current_job_offset
&& d->creature_strength_offset
&& d->creature_agility_offset
&& d->creature_toughness_offset
&& d->creature_skills_offset
&& d->creature_labors_offset
&& d->creature_happiness_offset
&& d->creature_traits_offset
// && d->creature_likes_offset
)
{
d->p_cre = new DfVector (d->p->readVector (creatures, 4)); d->p_cre = new DfVector (d->p->readVector (creatures, 4));
//InitReadNameTables(); //InitReadNameTables();
d->creaturesInited = true; d->creaturesInited = true;
numcreatures = d->p_cre->getSize(); numcreatures = d->p_cre->getSize();
return true; return true;
} }
else catch (Error::MissingMemoryDefinition&)
{ {
d->creaturesInited = false; d->creaturesInited = false;
numcreatures = 0; numcreatures = 0;
return false; throw;
} }
} }
bool API::InitReadNotes( uint32_t &numnotes ) bool API::InitReadNotes( uint32_t &numnotes )
{ {
try
{
memory_info * minfo = d->offset_descriptor; memory_info * minfo = d->offset_descriptor;
int notes = minfo->getAddress ("notes"); int notes = minfo->getAddress ("notes");
d->note_foreground_offset = minfo->getOffset ("note_foreground"); d->note_foreground_offset = minfo->getOffset ("note_foreground");
@ -967,23 +920,16 @@ bool API::InitReadNotes( uint32_t &numnotes )
d->note_name_offset = minfo->getOffset ("note_name"); d->note_name_offset = minfo->getOffset ("note_name");
d->note_xyz_offset = minfo->getOffset ("note_xyz"); d->note_xyz_offset = minfo->getOffset ("note_xyz");
if (notes
&& d->note_foreground_offset
&& d->note_background_offset
&& d->note_name_offset
&& d->note_xyz_offset
)
{
d->p_notes = new DfVector (d->p->readVector (notes, 4)); d->p_notes = new DfVector (d->p->readVector (notes, 4));
d->notesInited = true; d->notesInited = true;
numnotes = d->p_notes->getSize(); numnotes = d->p_notes->getSize();
return true; return true;
} }
else catch (Error::MissingMemoryDefinition&)
{ {
d->notesInited = false; d->notesInited = false;
numnotes = 0; numnotes = 0;
return false; throw;
} }
} }
bool API::ReadNote (const int32_t index, t_note & note) bool API::ReadNote (const int32_t index, t_note & note)
@ -1000,6 +946,8 @@ bool API::ReadNote (const int32_t index, t_note & note)
} }
bool API::InitReadSettlements( uint32_t & numsettlements ) bool API::InitReadSettlements( uint32_t & numsettlements )
{ {
try
{
memory_info * minfo = d->offset_descriptor; memory_info * minfo = d->offset_descriptor;
int allSettlements = minfo->getAddress ("settlements"); int allSettlements = minfo->getAddress ("settlements");
int currentSettlement = minfo->getAddress("settlement_current"); int currentSettlement = minfo->getAddress("settlement_current");
@ -1007,23 +955,17 @@ bool API::InitReadSettlements( uint32_t & numsettlements )
d->settlement_world_xy_offset = minfo->getOffset ("settlement_world_xy"); d->settlement_world_xy_offset = minfo->getOffset ("settlement_world_xy");
d->settlement_local_xy_offset = minfo->getOffset ("settlement_local_xy"); d->settlement_local_xy_offset = minfo->getOffset ("settlement_local_xy");
if (allSettlements && currentSettlement
&& d->settlement_name_offset
&& d->settlement_world_xy_offset
&& d->settlement_local_xy_offset
)
{
d->p_settlements = new DfVector (d->p->readVector (allSettlements, 4)); d->p_settlements = new DfVector (d->p->readVector (allSettlements, 4));
d->p_current_settlement = new DfVector(d->p->readVector(currentSettlement,4)); d->p_current_settlement = new DfVector(d->p->readVector(currentSettlement,4));
d->settlementsInited = true; d->settlementsInited = true;
numsettlements = d->p_settlements->getSize(); numsettlements = d->p_settlements->getSize();
return true; return true;
} }
else catch (Error::MissingMemoryDefinition&)
{ {
d->settlementsInited = false; d->settlementsInited = false;
numsettlements = 0; numsettlements = 0;
return false; throw;
} }
} }
bool API::ReadSettlement(const int32_t index, t_settlement & settlement) bool API::ReadSettlement(const int32_t index, t_settlement & settlement)
@ -1039,6 +981,7 @@ bool API::ReadSettlement(const int32_t index, t_settlement & settlement)
g_pProcess->read(temp + d->settlement_local_xy_offset, 4 * sizeof(int16_t), (uint8_t *) &settlement.local_x1); g_pProcess->read(temp + d->settlement_local_xy_offset, 4 * sizeof(int16_t), (uint8_t *) &settlement.local_x1);
return true; return true;
} }
bool API::ReadCurrentSettlement(t_settlement & settlement) bool API::ReadCurrentSettlement(t_settlement & settlement)
{ {
if(!d->settlementsInited) return false; if(!d->settlementsInited) return false;
@ -1070,21 +1013,21 @@ void API::FinishReadSettlements()
bool API::InitReadHotkeys( ) bool API::InitReadHotkeys( )
{ {
try
{
memory_info * minfo = d->offset_descriptor; memory_info * minfo = d->offset_descriptor;
d->hotkey_start = minfo->getAddress("hotkey_start"); d->hotkey_start = minfo->getAddress("hotkey_start");
d->hotkey_mode_offset = minfo->getOffset ("hotkey_mode"); d->hotkey_mode_offset = minfo->getOffset ("hotkey_mode");
d->hotkey_xyz_offset = minfo->getOffset("hotkey_xyz"); d->hotkey_xyz_offset = minfo->getOffset("hotkey_xyz");
d->hotkey_size = minfo->getHexValue("hotkey_size"); d->hotkey_size = minfo->getHexValue("hotkey_size");
if (d->hotkey_start && d->hotkey_mode_offset && d->hotkey_size)
{
d->hotkeyInited = true; d->hotkeyInited = true;
return true; return true;
} }
else catch (Error::MissingMemoryDefinition&)
{ {
d->hotkeyInited = false; d->hotkeyInited = false;
return false; throw;
} }
} }
bool API::ReadHotkeys(t_hotkey hotkeys[]) bool API::ReadHotkeys(t_hotkey hotkeys[])
@ -1157,6 +1100,7 @@ bool API::getItemIndexesInBox(vector<uint32_t> &indexes,
} }
} }
} }
return true;
} }
bool API::ReadCreature (const int32_t index, t_creature & furball) bool API::ReadCreature (const int32_t index, t_creature & furball)
@ -1241,12 +1185,12 @@ void API::WriteLabors(const uint32_t index, uint8_t labors[NUM_CREATURE_LABORS])
bool API::InitReadNameTables (map< string, vector<string> > & nameTable) bool API::InitReadNameTables (map< string, vector<string> > & nameTable)
{ {
try
{
int genericAddress = d->offset_descriptor->getAddress ("language_vector"); int genericAddress = d->offset_descriptor->getAddress ("language_vector");
int transAddress = d->offset_descriptor->getAddress ("translation_vector"); int transAddress = d->offset_descriptor->getAddress ("translation_vector");
int word_table_offset = d->offset_descriptor->getOffset ("word_table"); int word_table_offset = d->offset_descriptor->getOffset ("word_table");
if(genericAddress && transAddress && word_table_offset)
{
DfVector genericVec (d->p->readVector (genericAddress, 4)); DfVector genericVec (d->p->readVector (genericAddress, 4));
DfVector transVec (d->p->readVector (transAddress, 4)); DfVector transVec (d->p->readVector (transAddress, 4));
@ -1272,10 +1216,10 @@ bool API::InitReadNameTables (map< string, vector<string> > & nameTable)
d->nameTablesInited = true; d->nameTablesInited = true;
return true; return true;
} }
else catch (Error::MissingMemoryDefinition&)
{ {
d->nameTablesInited = false; d->nameTablesInited = false;
return false; throw;
} }
} }
@ -1386,14 +1330,16 @@ bool API::Attach()
// find a process (ProcessManager can find multiple when used properly) // find a process (ProcessManager can find multiple when used properly)
if (!d->pm->findProcessess()) if (!d->pm->findProcessess())
{ {
cerr << "couldn't find a suitable process" << endl; throw Error::NoProcess();
return false; //cerr << "couldn't find a suitable process" << endl;
//return false;
} }
d->p = (*d->pm) [0]; d->p = (*d->pm) [0];
if (!d->p->attach()) if (!d->p->attach())
{ {
cerr << "couldn't attach to process" << endl; throw Error::CantAttach();
return false; // couldn't attach to process, no go //cerr << "couldn't attach to process" << endl;
//return false; // couldn't attach to process, no go
} }
d->offset_descriptor = d->p->getDescriptor(); d->offset_descriptor = d->p->getDescriptor();
// process is attached, everything went just fine... hopefully // process is attached, everything went just fine... hopefully
@ -1456,6 +1402,8 @@ void API::WriteRaw (const uint32_t offset, const uint32_t size, uint8_t *source)
bool API::InitViewAndCursor() bool API::InitViewAndCursor()
{ {
try
{
d->window_x_offset = d->offset_descriptor->getAddress ("window_x"); d->window_x_offset = d->offset_descriptor->getAddress ("window_x");
d->window_y_offset = d->offset_descriptor->getAddress ("window_y"); d->window_y_offset = d->offset_descriptor->getAddress ("window_y");
d->window_z_offset = d->offset_descriptor->getAddress ("window_z"); d->window_z_offset = d->offset_descriptor->getAddress ("window_z");
@ -1466,30 +1414,27 @@ bool API::InitViewAndCursor()
d->pause_state_offset = d->offset_descriptor->getAddress ("pause_state"); d->pause_state_offset = d->offset_descriptor->getAddress ("pause_state");
d->view_screen_offset = d->offset_descriptor->getAddress ("view_screen"); d->view_screen_offset = d->offset_descriptor->getAddress ("view_screen");
if (d->window_x_offset && d->window_y_offset && d->window_z_offset &&
d->current_cursor_creature_offset && d->current_menu_state_offset &&
d->pause_state_offset && d->view_screen_offset)
{
d->cursorWindowInited = true; d->cursorWindowInited = true;
return true; return true;
} }
else catch (Error::MissingMemoryDefinition&)
{ {
return false; throw;
} }
} }
bool API::InitViewSize() bool API::InitViewSize()
{ {
d->window_dims_offset = d->offset_descriptor->getAddress ("window_dims"); try
if (d->window_dims_offset)
{ {
d->window_dims_offset = d->offset_descriptor->getAddress ("window_dims");
d->viewSizeInited = true; d->viewSizeInited = true;
return true; return true;
} }
else catch (Error::MissingMemoryDefinition&)
{ {
return false; throw;
} }
} }
@ -1567,21 +1512,21 @@ DFWindow * API::getWindow()
bool API::InitReadItems(uint32_t & numitems) bool API::InitReadItems(uint32_t & numitems)
{ {
try
{
int items = d->offset_descriptor->getAddress ("items"); int items = d->offset_descriptor->getAddress ("items");
d->item_material_offset = d->offset_descriptor->getOffset ("item_materials"); d->item_material_offset = d->offset_descriptor->getOffset ("item_materials");
if(items && d->item_material_offset)
{
d->p_itm = new DfVector (d->p->readVector (items, 4)); d->p_itm = new DfVector (d->p->readVector (items, 4));
d->itemsInited = true; d->itemsInited = true;
numitems = d->p_itm->getSize(); numitems = d->p_itm->getSize();
return true; return true;
} }
else catch (Error::MissingMemoryDefinition&)
{ {
d->itemsInited = false; d->itemsInited = false;
numitems = 0; numitems = 0;
return false; throw;
} }
} }
bool API::ReadItem (const uint32_t index, t_item & item) bool API::ReadItem (const uint32_t index, t_item & item)

@ -450,7 +450,7 @@ uint32_t memory_info::getAddress (const char *key)
{ {
return (*iter).second; return (*iter).second;
} }
return 0; throw Error::MissingMemoryDefinition("address", key);
} }
@ -462,7 +462,7 @@ uint32_t memory_info::getOffset (const char *key)
{ {
return (*iter).second; return (*iter).second;
} }
return 0; throw Error::MissingMemoryDefinition("offset", key);
} }
// Get named numerical value // Get named numerical value
@ -473,7 +473,7 @@ uint32_t memory_info::getHexValue (const char *key)
{ {
return (*iter).second; return (*iter).second;
} }
return 0; throw Error::MissingMemoryDefinition("hexvalue", key);
} }
@ -486,7 +486,7 @@ uint32_t memory_info::getAddress (const string &key)
{ {
return (*iter).second; return (*iter).second;
} }
return 0; throw Error::MissingMemoryDefinition("address", key.c_str());
} }
@ -498,7 +498,7 @@ uint32_t memory_info::getOffset (const string &key)
{ {
return (*iter).second; return (*iter).second;
} }
return 0; throw Error::MissingMemoryDefinition("offset", key.c_str());
} }
// Get named numerical value // Get named numerical value
@ -509,7 +509,7 @@ uint32_t memory_info::getHexValue (const string &key)
{ {
return (*iter).second; return (*iter).second;
} }
return 0; throw Error::MissingMemoryDefinition("hexvalue", key.c_str());
} }
// Get named string // Get named string
@ -520,7 +520,7 @@ std::string memory_info::getString (const string &key)
{ {
return (*iter).second; return (*iter).second;
} }
return string(""); throw Error::MissingMemoryDefinition("string", key.c_str());
} }
// Get Profession // Get Profession
@ -530,10 +530,7 @@ string memory_info::getProfession (const uint32_t key) const
{ {
return d->professions[key]; return d->professions[key];
} }
else throw Error::MissingMemoryDefinition("profession", key);
{
return string("");
}
} }
// Get Job // Get Job
@ -543,7 +540,7 @@ string memory_info::getJob (const uint32_t key) const
{ {
return d->jobs[key]; return d->jobs[key];
} }
return string("Job Does Not Exist"); throw Error::MissingMemoryDefinition("job", key);
} }
string memory_info::getSkill (const uint32_t key) const string memory_info::getSkill (const uint32_t key) const
@ -552,7 +549,7 @@ string memory_info::getSkill (const uint32_t key) const
{ {
return d->skills[key]; return d->skills[key];
} }
return string("Skill is not Defined"); throw Error::MissingMemoryDefinition("skill", key);
} }
// FIXME: ugly hack that needs to die // FIXME: ugly hack that needs to die
@ -585,7 +582,7 @@ string memory_info::getTrait (const uint32_t traitIdx, const uint32_t traitValue
else else
return d->traits[traitIdx][0]; return d->traits[traitIdx][0];
} }
return string("Trait is not Defined"); throw Error::MissingMemoryDefinition("trait", traitIdx);
} }
string memory_info::getTraitName(const uint32_t traitIdx) const string memory_info::getTraitName(const uint32_t traitIdx) const
@ -594,7 +591,7 @@ string memory_info::getTraitName(const uint32_t traitIdx) const
{ {
return d->traits[traitIdx][d->traits[traitIdx].size()-1]; return d->traits[traitIdx][d->traits[traitIdx].size()-1];
} }
return string("Trait is not Defined"); throw Error::MissingMemoryDefinition("traitname", traitIdx);
} }
string memory_info::getLabor (const uint32_t laborIdx) string memory_info::getLabor (const uint32_t laborIdx)
@ -603,7 +600,7 @@ string memory_info::getLabor (const uint32_t laborIdx)
{ {
return d->labors[laborIdx]; return d->labors[laborIdx];
} }
return string(""); throw Error::MissingMemoryDefinition("labor", laborIdx);
} }
// Reset everything // Reset everything