Kotlin/JS NPE Source Reference - javascript

I have a Kotlin/JS project that is throwing a null pointer exception, but I can't figure out where it is coming from. The source map in the browser references exceptionUtils.kt?24ab which is a generic wrapper for the javascript error:
#JsName("throwNPE")
internal fun throwNPE(message: String) {
throw NullPointerException(message)
}
The stack trace for the error shown in the javascript console is, likewise, referencing the javascript bridging code, not my actual Kotlin source:
"NullPointerException
at Object.captureStack (webpack-internal:///./kotlin-dce-dev/kotlin.js:38592:15)
at NullPointerException.Exception [as constructor] (webpack-internal:///./kotlin-dce-dev/kotlin.js:38925:14)
at NullPointerException.RuntimeException [as constructor] (webpack-internal:///./kotlin-dce-dev/kotlin.js:38951:17)
at RuntimeException_init_0 (webpack-internal:///./kotlin-dce-dev/kotlin.js:38962:24)
at new NullPointerException (webpack-internal:///./kotlin-dce-dev/kotlin.js:39071:7)
at Object.throwNPE (webpack-internal:///./kotlin-dce-dev/kotlin.js:42775:13)
at Kotlin.ensureNotNull (webpack-internal:///./kotlin-dce-dev/kotlin.js:748:35)
at main (webpack-internal:///./kotlin-dce-dev/my-app.js:68:27)
at Object.eval (webpack-internal:///./kotlin-dce-dev/my-app.js:431:3)
at eval (webpack-internal:///./kotlin-dce-dev/my-app.js:5:35)"
How can I trace this back to the actual Kotlin source for the exception?

Related

Get line of error/assertionError in postman

So I m getting an assertion error in postman, and the error looks like this:
There was an error in evaluating the test script: AssertionError: expected undefined to be a string
But i have 300 assertions for this API, and is virtually impossible to idenftify what assertion actually failed, is there a way for me to make postman show the line number that raised the assertionFail?
There is a way to get the line number if you dig down into this:
How do you find out the caller function in JavaScript?
Wrap your asserts in a very large try catch. Then print out the stack in the catch.
Details
Append the catch at the bottom. Something like this:
try {
// 300 asserts here
}catch (e) {
console.log(e);
console.log(`e.stack = ${e.stack}`);
}
When PM hits the assert you will see something like:
{type: "Error", name: "TypeError", message: "Cannot read property 'json' of undefined"}
e.stack = TypeError: Cannot read property 'json' of undefined
at Object.eval (eval at exec (evalmachine.<anonymous>:58:1931768), <anonymous>:89:30)
at u.exec (evalmachine.<anonymous>:58:1931803)
at t.exports (evalmachine.<anonymous>:58:5743)
at Object.<anonymous> (evalmachine.<anonymous>:58:7440)
at evalmachine.<anonymous>:15:26
at Array.forEach (<anonymous>)
at Object.emit (evalmachine.<anonymous>:14:54)
at evalmachine.<anonymous>:51:24
at evalmachine.<anonymous>:5:21
at evalmachine.<anonymous>:6:18
The top of the stack tells you the line number (zero-based):
at Object.eval (eval at exec (evalmachine.:58:1931768), :89:30)
So in this case 89, is reported as 88 in the IDE.
BTW it appears that the 30 is actually the column number of the called method.
Additional entries give a longer trace, showing the lineage of the calls before the error occurred, which may be useful in some debugging cases.
Warning this will cause the first assert error to interrupt any further testing. So undo this change when you are done.

Javascript try-catch semantics (call stack in nodejs repl)

I'm somewhat new to javascript, but I wanted to try to understand how stack-tracing works in nodejs. I was a little lazy to look at the source code, so I just consulted the language reference https://www.ecma-international.org/ecma-262/10.0/index.html#sec-runtime-semantics-catchclauseevaluation and tried to see what works. So, here is the mystery: in the repl I get some odd results when catching and throwing.
When I run:
try { throw Error('foo'); } catch (e) { throw e; }
I get as output:
Error: foo
But when I run:
try { throw Error('foo'); } catch (e) { console.log(e); throw e; }
I get as output:
Error: foo
at repl:1:13
at ContextifyScript.Script.runInThisContext (vm.js:50:33)
at REPLServer.defaultEval (repl.js:240:29)
at bound (domain.js:301:14)
at REPLServer.runBound [as eval] (domain.js:314:12)
at REPLServer.onLine (repl.js:468:10)
at emitOne (events.js:121:20)
at REPLServer.emit (events.js:211:7)
at REPLServer.Interface._onLine (readline.js:282:10)
at REPLServer.Interface._line (readline.js:631:8)
Error: foo
at repl:1:13
at ContextifyScript.Script.runInThisContext (vm.js:50:33)
at REPLServer.defaultEval (repl.js:240:29)
at bound (domain.js:301:14)
at REPLServer.runBound [as eval] (domain.js:314:12)
at REPLServer.onLine (repl.js:468:10)
at emitOne (events.js:121:20)
at REPLServer.emit (events.js:211:7)
at REPLServer.Interface._onLine (readline.js:282:10)
at REPLServer.Interface._line (readline.js:631:8)
It seems as though calling console.log(e) causes the error object to trace the execution context stack (I hope I'm using this term correctly), but if it passes through to the repl without the context.log(e) it only knows about its error message.
I've tried different permutations of this and also nesting in different lexical contexts (functions and another try-catch block), and they all seem to give this "funny" behavior. Also, when executing these as scripts I always get an expected error message and stack-trace, so I'm led to believe that the implementation of the repl is at fault here. However, before diving into the source, I wanted to probe some experts to see if there is some good reason for this behavior, or if it is just a stupid corner case that I've come up with.
Well, I don't know if it's kosher to answer my own question, but I dug into the nodejs source and found out what the deal is. I tracked it down to repl.js: line 404. Here there is a call to script.runInThisContext. At this point, the line throw new Error() "escapes" the repl and ends up getting caught a few lines below. Here, there is check for process.domain, which apparently succeeds in the repl, but not in a script context. This then emits a domain error, which doesn't do much. If you go to self._domain.on('error',... you will see that all the stack tracing stuff is taken care of here.
I actually added a line self._domain.emit('error'... to the source right before the process.domain.emit('error',... call, and it then printed out a nice stack trace for me, so I'll write the guys over at nodejs and see if it is something they would like to fix. There may be a very good reason not to do so, I didn't look into it in that great of detail.
At this point I'm reminded of a scene from Burn after Reading. Watch it if you have a dry sense of humor: https://www.youtube.com/watch?v=46h7oP9eiBk

Electron - Resize Window from renderer process

I am working on an Electron app and as part of the interface I want to increase the size of the window once something has happened (I have bound this to a button for now) so I can display additional data. I have attempted to do this with the following code that is activated on a onclick=resize():
require('./renderer.js');
let remote = require('electron').remote;
function resize() {
let win = remote.getCurrentWindow().setBounds({
height: 1000
});
}
However, I am getting the following error in the window/browser console:
Uncaught Error: Could not call remote function 'setBounds'. Check that the function signature is correct. Underlying error: Error processing argument at index 0, conversion failure from #<Object>
Error: Could not call remote function 'setBounds'. Check that the function signature is correct. Underlying error: Error processing argument at index 0, conversion failure from #<Object>
at callFunction (C:\Users\Thomas\AppData\Roaming\npm\node_modules\electron\dist\resources\electron.asar\browser\rpc-server.js:257:11)
at EventEmitter.<anonymous> (C:\Users\Thomas\AppData\Roaming\npm\node_modules\electron\dist\resources\electron.asar\browser\rpc-server.js:357:5)
at emitMany (events.js:127:13)
at EventEmitter.emit (events.js:204:7)
at WebContents.<anonymous> (C:\Users\Thomas\AppData\Roaming\npm\node_modules\electron\dist\resources\electron.asar\browser\api\web-contents.js:256:13)
at emitTwo (events.js:106:13)
at WebContents.emit (events.js:194:7)
at callFunction (C:\Users\Thomas\AppData\Roaming\npm\node_modules\electron\dist\resources\electron.asar\browser\rpc-server.js:257:11)
at EventEmitter.<anonymous> (C:\Users\Thomas\AppData\Roaming\npm\node_modules\electron\dist\resources\electron.asar\browser\rpc-server.js:357:5)
at emitMany (events.js:127:13)
at EventEmitter.emit (events.js:204:7)
at WebContents.<anonymous> (C:\Users\Thomas\AppData\Roaming\npm\node_modules\electron\dist\resources\electron.asar\browser\api\web-contents.js:256:13)
at emitTwo (events.js:106:13)
at WebContents.emit (events.js:194:7)
at metaToValue (C:\Users\Thomas\AppData\Roaming\npm\node_modules\electron\dist\resources\electron.asar\renderer\api\remote.js:234:13)
at Object.remoteMemberFunction (C:\Users\Thomas\AppData\Roaming\npm\node_modules\electron\dist\resources\electron.asar\renderer\api\remote.js:118:18)
at resize (file:///D:/Documents/Development/Projects/ShortenMeURL/V1/index.html:41:45)
at HTMLButtonElement.onclick (file:///D:/Documents/Development/Projects/ShortenMeURL/V1/index.html:22:86)
Any suggestions on how I can fix this?
Definition of Rectangle object (which is the first argument of setBounds) is more strict than you expected. Since its properties don't have default values you have to define all of them.
For example:
remote.getCurrentWindow().setBounds({
x: 1621,
y: 611,
width: 10,
height: 1000
});
Also, if you want to adjust only size you can use setSize of BrowserWindow
Just use plain old javascript from the renderer, I would not add an unnecessary messaging between main and renderer process if it is just a resize ;)
window.resizeTo(1000,900);
If anyone's getting a similar error, make sure you provide integer values, for example 123, not 123,45. Math.round them to make sure.
I don't see a mention of this in the documentation sadly.

Error with Ext.Msg in js-test-driver tests

In my js-test-driver tests, I'm having an error from simply calling
Ext.Msg.alert('Error', 'An error occurred while trying load parameters for action with id ' + actionId);
Error Message: Uncaught TypeError: Cannot read property 'insertBefore' of null
Note that Ext.Msg.rendered is true and that Ext.Msg.el.dom.parentNode is null if I stop execution just before the error.
This error does not happen if:
The real app is running, only during tests.
If I run a single test, only if I run multiple tests that end up calling Ext.Msg.alert
Stack trace
Ext.define.insertBefore (ext-all-debug.js:13281)
Ext.define.show (ext-all-debug.js:42064)
Ext.define.sync (ext-all-debug.js:82755)
Ext.define.syncShadow (ext-all-debug.js:33992)
Ext.define.onAfterFloatLayout (ext-all-debug.js:34002)
Ext.define.afterComponentLayout (ext-all-debug.js:34374)
Base.implement.callParent (ext-all-debug.js:4455)
Ext.define.afterComponentLayout (ext-all-debug.js:38639)
Ext.define.notifyOwner (ext-all-debug.js:38067)
Ext.define.callLayout (ext-all-debug.js:125114)
Ext.define.flushLayouts (ext-all-debug.js:125283)
Ext.define.runComplete (ext-all-debug.js:125769)
callOverrideParent (ext-all-debug.js:36)
Base.implement.callParent (ext-all-debug.js:4455)
Ext.override.runComplete (ext-all-debug.js:29905)
Ext.define.run (ext-all-debug.js:125750)
Ext.define.statics.flushLayouts (ext-all-debug.js:29913)
Ext.define.statics.updateLayout (ext-all-debug.js:29947)
Ext.define.updateLayout (ext-all-debug.js:31844)
Ext.define.onContentChange (ext-all-debug.js:36116)
Ext.define.updateLayout (ext-all-debug.js:31839)
Ext.define.onContentChange (ext-all-debug.js:36116)
Ext.define.updateLayout (ext-all-debug.js:31839)
Ext.define.setTitle (ext-all-debug.js:53058)
Ext.define.setTitle (ext-all-debug.js:55155)
Ext.define.reconfigure (ext-all-debug.js:90310)
Ext.define.show (ext-all-debug.js:90476)
Ext.define.alert (ext-all-debug.js:90600)
Ext.define.onInstanceRetrievalError (BaseWorkflowActionController.js:139)
(anonymous function) (ext-all-debug.js:2265)
Ext.apply.callback (ext-all-debug.js:7437)
Ext.define.Ext.apply.inheritableStatics.load (mock.js:38)
Ext.define.onDocumentClick (BaseWorkflowActionController.js:73)
(anonymous function) (VM6566:6)
Ext.apply.createListenerWrap.wrap (ext-all-debug.js:10786)
AsyncTestCase.test_unknown_error_displays_error_dialog (WorkflowSingleActionController.Test.js:87)
Any ideas of what could be going on? Or something to try?
This question was cross-posted to http://www.sencha.com/forum/showthread.php?288372-Error-calling-Ext.Msg.alert-from-js-test-driver-tests&p=1053744#post1053744
The problem is that js-test-driver runs the following code which removes any content from the DOM at the end of each test.
var testRunnerPlugin =
new jstestdriver.plugins.TestRunnerPlugin(Date, function() {
jstestdriver.log(jstestdriver.jQuery('body')[0].innerHTML);
jstestdriver.jQuery('body').children().remove();
jstestdriver.jQuery(document).unbind();
jstestdriver.jQuery(document).die();
}, runTestLoop);
Therefore, the global Ext.Msg which was rendered onto the body becomes orphaned and it fails when trying to sync the shadow.
The solution is not to use the global Ext.Msg, always instantiate a new Ext.message.MessageBox if you want your code to be testable in js-test-driver
Here's a test case that reproduces the exact same stack trace https://fiddle.sencha.com/#fiddle/7i1

Stack traces that utilise source mapping

Overview:
The stack trace output in the browser console is not the same trace that is returned when Error.stack is called. The console stack trace seems to take into account sourcemaps whereas the Error.stack stack trace does not.
Console Output
Here is the default stack trace that is output to the console.
Uncaught TypeError: Cannot set property 'y' of undefined source.js:4
(anonymous function) source.js:4
(anonymous function) source.js:4
(anonymous function) (index):17
Error.stack Output
Here is the stack trace from Error.stack:
TypeError: Cannot set property 'y' of undefined
at <anonymous>:1:37
at <anonymous>:1:60
at http://localhost:63342/source-map-example/example2/:17:23 (index):12
Source Code:
Here is the code that I used for this experiment:
<script>
window.onerror = function() {
console.log(arguments[4].stack);
}
var script = document.createElement('script');
script.textContent = '(function(){var person={};person.x.y="Throws an error..."})();//# sourceMappingURL=source.min.map';
document.body.appendChild(script);
</script>
Question:
Is it possible to programmatically obtain a stack trace that includes references to files & lines based on the associated sourcemap?
Edit: console.trace and new Error().stack
note: I didn't use window.onerror for these examples, instead I wrapped the embedded JS in a try...catch and attempted to utilise these approaches within the catch. The reason for this was because the stack trace didn't provide any trace into the embedded JS for either method when used within window.onerror.
console.trace() works the best, but of course the output can't be captured. Even still, this does not work as expected. The output contains a stack trace that points to the console.trace() line, and little else.
console.trace() source.js:9
(anonymous function) source.js:9
(anonymous function) source.js:9
(anonymous function)
new Error().stack does not work as expected either. It does contain a stack trace, but it's not using the sourcemap.
Error
at <anonymous>:1:85
at <anonymous>:1:105
at http://localhost:63342/source-map-example/example2/:18:23 source.js:18
Unfortunately, this is browser-specific feature is not currently supported in either Firefox or Chrome (and I am unfamiliar with its support in other browsers).
In Chrome, you can follow feature request currently being implemented at https://code.google.com/p/chromium/issues/detail?id=357958
Depending on your use case and if you have some means of capturing the sourcemaps themselves, Mozilla has an excellent sourcemapping tool that will let you map your sources/stacktraces at https://github.com/mozilla/source-map/.

Categories

Resources