I am trying to test something here.
I am using electron and javascript. I am trying to load a profile into the page when a user selects it. None of my console log statements are showing in the console, however when the user makes the "profileSelect" change event, the values are loaded correctly. The reason I am testing this is because I am trying to add an addition to this file, checking a checkbox (it's not working either).
profileSelect.change(function(event) {
//If the value isn't null
console.log('yo')
if (profileSelect.val() == '') {
clearBilling();
} else {
ipcRenderer.once(profileSelect.val() + 'profileData', function(event, data) {
//Return card to style it was first added like
console.log('sshi')
//This allows us to parse the data on profile save
const cardParse = String(data.card.number).match(/.{3,4}/g).join(' ')
const dateParse = String(data.card.month) + ' / ' + String(data.card.year);
profileName.val(profileSelect.val());
billingFirstName.val(data.billing.firstName);
billingLastName.val(data.billing.lastName);
billingAddress1.val(data.billing.address1);
billingAddress2.val(data.billing.address2);
billingCity.val(data.billing.city);
billingState.val(data.billing.state);
billingZipcode.val(data.billing.zipcode);
billingCountry.val(data.billing.country);
billingPhone.val(data.billing.phone);
billingEmail.val(data.email);
shippingFirstName.val(data.shipping.firstName);
shippingLastName.val(data.shipping.lastName);
shippingAddress1.val(data.shipping.address1);
shippingAddress2.val(data.shipping.address2);
shippingCity.val(data.shipping.city);
shippingState.val(data.shipping.state);
shippingZipcode.val(data.shipping.zipcode);
shippingCountry.val(data.shipping.country);
shippingPhone.val(data.shipping.phone);
cardName.val(data.card.name);
cardNumber.val(cardParse);
cardCVV.val(data.card.code);
cardExpire.val(dateParse);
})
//Send the selected profile
ipcRenderer.send('requestProfile', profileSelect.val())
}
})
Why aren't the console log statements logging? Thanks for any input :)
Electron has 2 processes, and hence 2 consoles. The 2 processes are main and renderer, main being a node.js process, renderer being a browser process.
Main process console.log would be shown in the terminal (if running in dev) or in the browser console window if in the renderer process.
You seem to be logging from the renderer process as per the ipcRenderer statements.
The renderer console can be shown via the standard chrome devtools shortcut (as its running a chrome instance) (usually F12)
You won't be able to see any console statements from renderer in main, or main in renderer.
Related
In my electron app I'd like to use console.trace() but want it to be collapsed by default. For that I use this in renderer process:
{
const {groupCollapsed, groupEnd, trace} = console;
console.trace = ((...args:any[]) =>
{
groupCollapsed(...args);
trace("");
groupEnd();
}).bind(console);
}
It works ok (time to time few messages from async functions getting grouped together), however in main process I'm bombarded by these messages (each trace call generates several lines):
[34352:0406/075851.692:ERROR:CONSOLE(6)] "console.assert", source: devtools://devtools/bundled/panels/console/console.js (6)
I'm unable reproduce this exact message with an electron snippet using electron v18.0.2, but it shows similar message instead:
[5636:0406/083113.750:INFO:CONSOLE(5)] "test", source: file:///C:/Users/dev/AppData/Local/Temp/tmp-34776-vztptWEofKLe/renderer.js (5)
[5636:0406/083113.751:INFO:CONSOLE(7)] "console.groupEnd", source: file:///C:/Users/dev/AppData/Local/Temp/tmp-34776-vztptWEofKLe/renderer.js (7)
so how can I see where that error is coming from (aka devtools://devtools/bundled/panels/console/console.js) and most importantly how to suppress it?
[EDIT]
This seems to have nothing to do with me replacing console.trace. It seems the issue is in electron itself. The last version that didn't have this issue was 18.0.0-alpha.5, since 18.0.0-beta.1 these messages appear. If I clear developer tools console, the messages stop for a while, but after some time they start showing up again with each message in dev tools.
My objective: Test out my error handling functionality.
Temporary solution: Have a custom route: /error, which contains code which purposefully produces fatal error.
var a = undefined;
a.b.c // Breaks.
The above works, but I can't use it to test production site as the page is not required.
I was looking for a way to test it via the browser. I tried simply adding"
throw new Error("Custom error thrown here") to the console. That doesn't actually break it during runtime.
I tried adding a break point and adding the same code: throw new Error("Custom error thrown here"). That didn't work either.
Any other easier ways to do this rather than the above?
I was looking for a way where I can do it via browser only.
Thanks.
You did not clearly mention how and where the error should be thrown. I will assume that you can use a modified copy of your JavaScript file to throw errors. The modified file will reside on your computer and only be used when you're using Chrome developer tools. This feature is called Local Overrides. The steps are as follows:
Open the webpage
Open Chrome developer tools for that webpage
In Sources panel go to Overrides tab
Click Select folder for overrides and choose a folder on your computer
A warning appears on the webpage which reads "DevTools requests full access to ..." which you must allow
In Sources panel go to Page tab
Locate the file in which you need to inject the "throw error" code
Right click and choose Save for overrides
Now you can edit the copy of the file on your computer or from within developer tools. Insert the code that produces the error at the desired location. When you reload the page with developer tools open, Chrome will load the local copy of the JavaScript file and throw the error. The error thrown that way will contain the context from where it originated e.g. call stack. If the developer tools are closed then live copy will be used.
If I got your question right, this is How you can do it from the console:
var script_tag = document.createElement('script');
script_tag.type = 'text/javascript';
script_tag.text = 'throw new Error("Custom error thrown here")';
document.body.appendChild(script_tag);
Or if you want you can trigger it on click:
var script_tag = document.createElement('script');
script_tag.type = 'text/javascript';
script_tag.text = 'window.document.onclick = function() { throw new Error("Custom error thrown here")}';
document.body.appendChild(script_tag);
And then you click anywhere on the page, to throw the error;
I would use the exec function which actually takes string and runs the code within at compile time.
exec('a.b.c')
You won't be able to throw an error inside your application from the console, since you are out of scope of the app.
Having said that, one slightly awkward way you could do this is by adding a breakpoint at the start of the javascript file.
Reload the page and your app will pause at the breakpoint - you can then modify the code as you need - like adding a throw new Error("something...") - and save your edits.
Then allow the code to run and you will see your error.
A downside is if you reload the changes will be gone, but I believe it's as close as you can get to modifying code at runtime.
Add this code to your production code
window.addEventListener('err', () => {
throw new Error('break it');
})
and when you want to create an error simply
dispatchEvent(new Event('err'))
in the console
You can use a global variable, which is accessible from your app and from debug console.
if (window.shouldThrow) {
throw new Error("Custom error thrown here");
}
This way you can turn on/off the exception throwing using the window.shouldThrow variable.
Try this way to catch error detail on run time
try
{
var a = undefined;
a.b.c // Breaks.
}
catch ( e )
{
alert("Error: " + e.description );
}
Currently I need to get command line arguments from an Electron application. So if you start the application with command line arguments, I need to use the arguments within the renderer process (a webview to be specific.)
This works fine when opening the application for the first time (using onload), but I'm having issues getting this to work when the application is already running and the user tries to reopen the app from cmd with args.
Currently, I'm using:
let closeDupeApp = app.makeSingleInstance(function(commandLine, workingDirectory) {
// Someone tried to run a second instance, we should focus our window.
if (mainWindow) {
if (mainWindow.isMinimized()) mainWindow.restore();
mainWindow.focus();
}
});
To prevent a second window from opening. However, I need the commandLine arguments and I need to send them to the renderer process.
Is there a way to do this?
You can read process.argv in the main process and paste it onto the end of the file:// url as a query string in BrowserWindow.open(). I do this routinely. You can JSON encode the and encodeURIComponent on the array to get a nice list in the renderer process.
Found a solution:
main.js
let closeDupeApp = app.makeSingleInstance(function(commandLine, workingDirectory) {
if (mainWindow) {
// Send args to renderer
mainWindow.webContents.send("cmdArgs", commandLine);
if (mainWindow.isMinimized()) mainWindow.restore();
mainWindow.focus();
}
});
rendererFile.js
require('electron').ipcRenderer.on('cmdArgs', function(event, cmdArgs) {
// STUFF
}
I am also using angular and electron, but everything worked fine previously. This is the error:
Error: SCardConnect error:
SCardConnect error: The smart card cannot be accessed because of other connections outstanding.
(0x8010000b)
After the first time scanning a card, it no longer throws error and works fine reading cards until relaunch. Here are some snippets of my code relevant to smartcard:
const smartcard = require('smartcard');
const Devices = smartcard.Devices;
const devices = new Devices();
let currentDevices = [];
//something else
app.run(function($rootScope) {
let registerDevices = function (event) {
currentDevices = event.devices;
currentDevices.forEach(function (device) {
device.on('card-inserted', event => {
let card = event.card;
console.log(`Card '${card.getAtr()}' inserted into '${card.device}'`);
$rootScope.$broadcast('card-attach',card.getAtr());
});
device.on('card-removed', event => {
});
device.on('error', event => {
console.error("Card Reader Error: " + event);
});
});
};
devices.on('device-activated', event => {
console.log("Reader added :" + event.device);
registerDevices(event);
});
devices.on('device-deactivated', event => {
console.log("Reader removed :" + event.device);
registerDevices(event);
});
});
In addition, when I disconnect the scanner, it says
events.js:160 Uncaught Error: SCardListReaders error: The Smart Card Resource Manager is not running.
(0x8010001d)
events.js:163 Uncaught Error: Uncaught, unspecified "error" event. ([object Object])
And the scanner is not working after reconnect.
This error code is E_SHARING_VIOLATION -- some process has already connected to the card in exclusive mode (using SCARD_SHARE_EXCLUSIVE for SCardConnect).
[Assuming you are under Windows]:
There is a Plug&Play mechanism in Windows which by default automatically accesses every card immediately after insertion and tries to determine the correct driver for it -- which creates a short time window when the card is being accessed (this is IMHO the most probable cause).
You have two choices:
Deal with it -- retry the card connection attempt after some time (tens of ms, YMMV) for this particular error code (possibly could be done in loop with some max retry count).
Disable this behavior -- there are two ways (I have never used the Group Policy one, but it should work):
a/ using Local Group Policy Settings (disable Computer Configuration -> Administrative Templates -> Windows Components -> Smart Card -> Turn On Smart Card Plug and Play Service) (see e.g. here)
b/ by setting the registry key EnableScPnP under HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\ScPnP to dword:0x00000000 (for a 64-bit system set it under HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Policies\Microsoft\Windows\ScPnP as well) -- see e.g. here. Be sure to reboot your system for the change to take effect
Regarding your edit with the 0x8010001D (E_NO_SERVICE) error code and reconnecting a reader -- I have no idea.
Good luck!
I have started looking at tutorials for making TVML/TVJS based apps for the new Apple TV, and I have two problems that makes the development process very tedious and impractical.
First thing I am having trouble understanding is how I am supposed to debug code that happens on startup of the application. I have connected the Safari debugger, and I do manage to hit some breakpoints, but only for code that is triggered by some user input. On startup I am loading an xml document from a remote location, and I will use this to dynamically generate the tvml template, but I cannot get the debugger to stop anywhere in the code that is running before the template is done rendering.
The other anti-productive problem I have is that I cannot seem to reload the JavaScript files in any other way than completely shutting down the application in the simulator (double-click the home button, and swipe the app away). This also makes the debugger quit, so I have to restart that one as well. This surely cannot be the way you are supposed to do continuous development and testing?
You can make the debugger stop at the first line when you choose the Auto Pause and Auto Show options from the Safari menu "Develop/Simulator".
You are correct about the exit issue.
One thing you can also try is to run App.reload() from the Safari Debugger console.
This also restarts the app, maybe in the future they can make it work so the debugger will not be gone.
But at the moment this also does not solve the issue.
For manual debugger output (aka console.log()), you could redirect the logging to the Xcode debugger.
(somewhere on the web) I found a way to actually do that, in short it looks like...
AppDelegate.Swift
func appController(appController: TVApplicationController, evaluateAppJavaScriptInContext jsContext: JSContext) {
let jsInterface: cJsInterface = cJsInterface();
jsContext.setObject(jsInterface, forKeyedSubscript: "swiftInterface")
}
App.js
// re-route console.log() to XCode debug window
var console = {
log: function() {
var message = '';
for(var i = 0; i < arguments.length; i++) {
message += arguments[i] + ' '
};
swiftInterface.log(message)
}
};
JsInterface.Swift
#objc protocol jsInterfaceProtocol : JSExport {
func log(message: String) -> Void
}
...
class cJsInterface: NSObject, jsInterfaceProtocol {
func log(message: String) -> Void {
print("JS: \(message)")
}
}
Complete sources in github: https://github.com/iBaa/PlexConnectApp/tree/f512dfd9c1cb2fbfed2da43c4e3837435b0b22af
I don't have any solution for the dying debugger myself...