<html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class="">Hi Otto,<br class=""><div><br class=""><blockquote type="cite" class=""><div class=""><div style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;" class="">When an object does not exist, the method has always returned nil. I've never seen an exception thrown when calling _objectForOop:</div></div></blockquote><div><br class=""></div><div>We only see this happening after an MFC and only occasionally and also only from within gems that have been running before the MFC. </div><div>Since the oop lookup is part of rendering the log entries in our Seaside application, connected users can trigger this error. The stack trace I pasted was triggered multiple times from the same gem, while Seaside requests handled by other gems were processing the same data (i.e. log entries) without errors at the same time (probably getting a nil result for the objectForOop:, as expected).</div><div><br class=""></div><blockquote type="cite" class=""><div class=""><div style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;" class="">The stack trace entry for </div><div style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;" class=""><span style="color: rgb(68, 68, 68); font-family: Consolas, "Liberation Mono", Courier, monospace, EmojiFontFace; white-space: pre-wrap; background-color: rgb(248, 248, 248);" class="">privateObjectAtUniqueIdentifie</span><span style="color: rgb(68, 68, 68); font-family: Consolas, "Liberation Mono", Courier, monospace, EmojiFontFace; white-space: pre-wrap; background-color: rgb(248, 248, 248);" class="">r:in:ifAbsent:</span><br class=""></div><div style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;" class="">does not tell me what is happening. Perhaps this is optimised by the compiler? How do you know that this is calling _objectForOop: and that it is _objectForOop: that raises the <span style="background-color: rgb(248, 248, 248); color: rgb(68, 68, 68); font-family: Consolas, "Liberation Mono", Courier, monospace, EmojiFontFace; white-space: pre-wrap;" class="">InternalError</span>?</div></div></blockquote></div><br class=""><div class="">It _is_ calling _objectForOop: but you are right: the stack trace does indeed not show this. In fact, there are several method calls in between <span style="color: rgb(68, 68, 68); font-family: Consolas, "Liberation Mono", Courier, monospace, EmojiFontFace; white-space: pre-wrap; background-color: rgb(248, 248, 248);" class="">privateObjectAtUniqueIdentifie</span><span style="color: rgb(68, 68, 68); font-family: Consolas, "Liberation Mono", Courier, monospace, EmojiFontFace; white-space: pre-wrap; background-color: rgb(248, 248, 248);" class="">r:in:ifAbsent: </span>and _objectForOop: …. The _objectForOop: send occurs in another method with a similar name `<span class="" style="color: rgb(68, 68, 68); font-family: Consolas, "Liberation Mono", Courier, monospace, EmojiFontFace; white-space: pre-wrap; background-color: rgb(248, 248, 248);">privateObjectAtUniqueIdentifie</span><span class="" style="color: rgb(68, 68, 68); font-family: Consolas, "Liberation Mono", Courier, monospace, EmojiFontFace; white-space: pre-wrap; background-color: rgb(248, 248, 248);">r:ifAbsent:`</span> which is implemented on another class, but it _is_ being called from NPLogEntry>>privateObjectAtUniqueIdentifier:in:ifAbsent: </div><div class="">Thanks for point that out… the similarity in names made me miss that.</div><div class=""><br class=""></div><div class="">So, the error probably occurs at the first access to the instance variable of the object we retrieved via _objectForOop:. Since the place in the stack trace where the error is thrown is indeed the first time we access the instVar with the object that is reported missing, that is probably what is happening. Indeed.</div><div class=""><br class=""></div><div class="">Unfortunately, I would expect _oopIsDead: to report the object as being dead in that case and thus not return us the object. </div><div class="">The implementation where we invoke _objectForOop: is shown below. First the version of the method as it was when the error occurred then the new version where I tried to the ‘fix’ it by wrapping the error handler around the entire code.</div><div class=""><div class=""><br class=""></div><div class=""><div class="">privateObjectAtUniqueIdentifier: anInteger ifAbsent: aBlock</div><div class=""><span class="Apple-tab-span" style="white-space:pre"> </span>^ (Object _objectForOop: anInteger)</div><div class=""><span class="Apple-tab-span" style="white-space:pre"> </span>ifNil: aBlock</div><div class=""><span class="Apple-tab-span" style="white-space:pre"> </span>ifNotNil:[ :object | [ (SystemRepository _oopIsDead: anInteger)</div><div class=""><span class="Apple-tab-span" style="white-space:pre"> </span>ifTrue: aBlock</div><div class=""><span class="Apple-tab-span" style="white-space:pre"> </span>ifFalse: [ object ] ] on: Error do: [:e | aBlock value ] ]</div><div class=""><br class=""></div><div class=""><br class=""></div><div class=""><div class="">privateObjectAtUniqueIdentifier: anInteger ifAbsent: aBlock</div><div class=""><span class="Apple-tab-span" style="white-space: pre;"> </span>^ [ (Object _objectForOop: anInteger)</div><div class=""><span class="Apple-tab-span" style="white-space: pre;"> </span>ifNil: aBlock</div><div class=""><span class="Apple-tab-span" style="white-space: pre;"> </span>ifNotNil:[ :object | (SystemRepository _oopIsDead: anInteger)</div><div class=""><span class="Apple-tab-span" style="white-space: pre;"> </span>ifTrue: aBlock</div><div class=""><span class="Apple-tab-span" style="white-space: pre;"> </span>ifFalse: [ object ] ] </div><div class=""><span class="Apple-tab-span" style="white-space: pre;"> </span>] on: Error do: [:e | </div><div class=""><span class="Apple-tab-span" style="white-space: pre;"> </span>"oop fishing in GemStone may return internal objects that do not implement ifNil:ifNotNil:.</div><div class=""><span class="Apple-tab-span" style="white-space: pre;"> </span>_oopIsDead can also error (see method comment). </div><div class=""><span class="Apple-tab-span" style="white-space: pre;"> </span>capture these objects here and return nil"</div><div class=""><span class="Apple-tab-span" style="white-space: pre;"> </span>aBlock value ]</div></div></div></div></body></html>