M
mzdude
During a code review the other day I noticed we have some
code that could be refactored.
Err.h
struct Error {
int errCode;
std::wstring reason;
Error(int e, wchar_t const *r )
: errCode(e)
, reason(r)
{}
};
const int ErrCode1 = 1000;
const int Errcode2 = 1001;
....
File1.cpp
void SomeFunct() {
if(cond)
throw Error( ErrCode1, L"This is an error");
}
File2.cpp
void AnotherFunc() {
if(cond)
throw Error( ErrCode1, L"This is an Error.");
}
Note the slight discrepancy in the error strings.
Obviously refactoring is the key to consistency.
But how to refactor?
In Err.h
// option 1, function returns object
Error Error_Code1()
{ return Error(ErrCode1, L"This is an error"); }
// option 2, single definition of a static object
// in this case all ErrCodeX's go away
extern Error Error_Code1;
// option 3, function actually does the throw
void ThrowError_Code1()
{ throw Error(ErrCode1, L"This is an error"); }
void SomeFunct() {
if(cond)
throw Error_Code1();
if(cond)
throw Error_Code1;
if(cond)
ThrowError_Code1();
My current preference is leaning towards option 1 for
several reason. No time wasted in constructing lots
of exceptions at start up time (as compared to option 2).
Option 3 hides what is happening when tracing through
the higher level code. It is only the function name that
makes it obvious.
In the future, this code **may** get internationalized,
in which case the string would move to a resource file.
code that could be refactored.
Err.h
struct Error {
int errCode;
std::wstring reason;
Error(int e, wchar_t const *r )
: errCode(e)
, reason(r)
{}
};
const int ErrCode1 = 1000;
const int Errcode2 = 1001;
....
File1.cpp
void SomeFunct() {
if(cond)
throw Error( ErrCode1, L"This is an error");
}
File2.cpp
void AnotherFunc() {
if(cond)
throw Error( ErrCode1, L"This is an Error.");
}
Note the slight discrepancy in the error strings.
Obviously refactoring is the key to consistency.
But how to refactor?
In Err.h
// option 1, function returns object
Error Error_Code1()
{ return Error(ErrCode1, L"This is an error"); }
// option 2, single definition of a static object
// in this case all ErrCodeX's go away
extern Error Error_Code1;
// option 3, function actually does the throw
void ThrowError_Code1()
{ throw Error(ErrCode1, L"This is an error"); }
void SomeFunct() {
if(cond)
throw Error_Code1();
if(cond)
throw Error_Code1;
if(cond)
ThrowError_Code1();
My current preference is leaning towards option 1 for
several reason. No time wasted in constructing lots
of exceptions at start up time (as compared to option 2).
Option 3 hides what is happening when tracing through
the higher level code. It is only the function name that
makes it obvious.
In the future, this code **may** get internationalized,
in which case the string would move to a resource file.