[ Home | CW Bug Reports | Mail ]
LModelObject::GetModelToken() error処理
Subject: BUG -- PP1.9.3 LModelObject::GetModelToken() error handling problem
---------------------------------------------------------------------------
METROWERKS PRODUCT AND USAGE SECTION
Product name : [ CodeWarrior Professional ]
Product version : [ Pro 4 ]
Component name : [ PowerPlant 1.9.3]
Generating: [ Mac OS 68K / Mac OS PowerPC ]
Purpose: [ application ]
---------------------------------------------------------------------------
BUG DESCRIPTION SECTION
Reason for this report: [ incorrect program feature ]
Bug severity: [ executes incorrectly ]
Reproducibility: [ always ]
Problem summary:
LModelObject::GetModelToken() should not throw here. If the
LModelObject has DefaultSubModel and failed to get a ModelToken from
it, this always throws.
// "this" model object
if (outToken.descriptorType == typeNull) {
try {
GetModelTokenSelf(inModelID, inKeyForm, inKeyData, outToken);
}
catch (ExceptionCode inErr) {
err = (OSErr) inErr;
}
catch (...) {
err = errAENoSuchObject;
}
// Fall through
}
// if (err != noErr) { // Error getting token
// Throw_(err);
// }
The better code is the following.
If both defaultModel and thisModel failed, it is the real error.
And I think you should add the Handle size comparison as a precaution.
void LModelObject::GetModelToken(DescType inModelID,
DescType inKeyForm,
const AEDesc& inKeyData,
AEDesc& outToken) const
{
OSErr defaultModelErr = noErr;
OSErr thisModelErr = noErr;
AEDesc originalOutToken = outToken;
Assert_( outToken.descriptorType == typeNull
|| outToken.descriptorType == type_ModelToken
|| outToken.descriptorType == typeAEList);
const SInt32 orgHandleSize = outToken.dataHandle ?
::GetHandleSize(outToken.dataHandle) : 0;
// Recursively try default submodel(s)
if (GetDefaultSubModel() != nil) {
StDisableDebugThrow_(); // Ok to fail
try {
GetDefaultSubModel()->GetModelToken(inModelID,inKeyForm,
inKeyData,outToken);
}
catch (ExceptionCode inErr) {
defaultModelErr = (OSErr)inErr;
}
catch (...) {
defaultModelErr = errAENoSuchObject;
}
// Fall through
}
// "this" model object
if (outToken.descriptorType == typeNull) {
try {
GetModelTokenSelf(inModelID,inKeyForm,inKeyData,outToken);
}
catch (ExceptionCode inErr) {
thisModelErr = (OSErr)inErr;
}
catch (...) {
thisModelErr = errAENoSuchObject;
}
// Fall through
}
if ((defaultModelErr != noErr) && (thisModelErr != noErr)) {
ThrowOSErr_(thisModelErr);
}
const SInt32 outHandleSize = outToken.dataHandle ?
::GetHandleSize(outToken.dataHandle) : 0;
// If the outToken has not changed since entry to this function,
// then we didn't get a valid token. This is an error.
if ( (outToken.descriptorType == originalOutToken.descriptorType)
&& (outToken.dataHandle == originalOutToken.dataHandle)
&& (outHandleSize == orgHandleSize)) {
ThrowOSErr_(errAENoSuchObject);
}
}
この Pageは MacOS X + Radio UserLand で作っています。