as you may all-ready know lastError is a global variable or property from chrome.runtime API used for determining if some error happened during the chrome API call execution.
It is defined only when there was an error, if the API call is OK it won't be defined. The error can be triggered from multiple reasons eg. bad API call due to missing or wrong parameter type, or it can be caused by user interaction, eg. the user rejects permission granting by pressing the "cancel" button.
Chrome has unified it's error handling by using this variable for error reporting across their API's instead of returning an error argument. Due to it's API's async nature Chrome makes an additional check that validates if chrome.runtime.lastError is checked/handled in the callback function from the extension code, if not it throws the famous Unchecked runtime.lastError
You can quickly get the error message by checking chrome.runtime.lastError.message and display it to the user, and all of this is great for most use cases, but I wouldn't write this question if that were my case.
So what happens when you need to implement some additional code logic based on the error result. Let's take launchWebAuthFlow for an example, for the sake of simplicity of the question, I will focus only on the two possible outcomes/errors that can happen:
User interaction required. thrown when API call with bad argument value is made, in this case interactive = false
The user did not approve access. happens when the user closes the authentication window
So my question is, what will be the best way to implement additional logic based on the error?
Is a comparison of chrome.runtime.lastError.message the only way to do it, and if so, is it safe considering that the user browser language might be different than English.
What's your opinion, should Chromium dev team implement: chrome.runtime.lastError.code?
Related
I have a "ghost" express middleware, that is sometimes triggered to check stuff before a request gets answered. As it relies on some sort of reverse engineering, there's a high chance it encounters unhandled errors. I call it "ghost" precisely because it should NEVER end the request if it has an error.
Except I want these unhandled errors to be logged in Sentry, while at the same time passing the request to the next request handler. Is there any Sentry method that allows sending errors without throwing them?
For now, I simply log them with Winston at the "error" priority level, but I'm really trying to transition away from that with Sentry. Sentry contexts seem to be related with what I'm trying to do, but I didn't quite get what they are.
My bad, should have read the docs more carefully. https://docs.sentry.io/platforms/node/enriching-events/context/#passing-context-directly
I am quite unsure how I should properly handle uncaught exceptions that occurs in my node.js/express app. Right now I have an Express app that will send all caught errors to an Express error handeler using next(err):
function(err, req, res, next) {
// Do something with the error
}
This seems to work all fine and well for errors I have anticipated. For instance a database connection not working, essentially all things that will return a callback(err). Thought problem occurs when I want to preform a background task, which will finish after the response has been sent. For instance:
app.get('/url', function(req, res) {
BackgroundTask.run() // Here an uncaught exception occurs, for instance a bug
res.send('Running your background task')
}
The background modules that I want to run aren't express related (no use of req,res) and upon a caught errors they will use a custom in errorHandeler that will send the error to some error reporting service. However when an uncaught exception occurs in one of these background tasks I have no clue how to send the error to my error report service (Raygun in this case). The only thing that seems to work is to add a process.on('uncaughtException') event listener. However almost every post on the subject describes the latter a 'bad' or crude way of doing things. They seems to recommand using node domains however I don't really see how I can implement these for background tasks.
I use process.on(uncaughtException), because all you're really trying to do is catch the output from the error and shut the server down gracefully (and then restart). I don't see any reason to do anything more complicated than that, because by nature of the exception, you don't want your application doing anything else in that state other than shutting down.
Domains are an alternative way of dealing with this, but it's not necessarily better than using the process handler, because you're effectively writing custom logic to handle things that you aren't anticipating. It does give you finer granularity in terms of what your error handler does for different error types, but ultimately you're still potentially running your application in an unknown state after handling it. I'd rather have my application log the exception, shut down, and then i'll fix the error so it never happens again, rather than risking my user's data on a domain solution which may or may not have handled the error correctly, depending on the nuance of the error it encountered.
What I would like to be able to do is access the gmail/calendar api using javascript from within a gmail contextual gadget (rather than bouncing the requests out to somewhere else).
I also want to do this using a service account for authentication so access is controlled via the gadget setup/domain and the user is never prompted for any details themselves.
The documentation around this area is a mass of out dated and confusing information, so it's hard to even tell if this is meant to be possible or not.
I have run through a number of different approaches with little success.
According to here https://developers.google.com/gadgets/docs/basic?csw=1 writing OAuth gadgets is no longer supported. Spent a lot of time getting nowhere with this approach before noticing that comment, and abandoning it.
Next, tried using gadgets.io.makeRequest from https://developers.google.com/gadgets/docs/reference/#gadgets.io but this didn't seem the right fit for what I wanted, too much of a roll your own solution. I had no success with that, so abandoned it to try something else.
Next tried gapi.auth.authorize https://developers.google.com/api-client-library/javascript/features/authentication This one seemed promising at first, but I cannot find any information on using it with a service account, and I just get errors when trying to use it (but at least errors feel like moving forwards!).
My current code for this is along the lines of
function connectToGmail() {
gapi.client.setApiKey(API_KEY);
window.setTimeout(checkAuth,1);
}
function checkAuth() {
var parameters = {
client_id: OAUTH2_CLIENT_ID,
scope: OAUTH2_SCOPES,
immediate: true,
output: 'embedded'
};
gapi.auth.authorize(parameters, function(result) {
console.log('login complete');
console.log(gapi.auth.getToken());
});
}
but the authorize callback is never called.
Have tried adding hd: to the parameters too, and a few other undocumented values I've seen used in my hunt for details.
In various experiments I generally this error in the browser console
Refused to display 'https://accounts.google.com/o/oauth2/auth?client_id=**********.googleusercontent.com&response_type=token&state=1847286098%7C0.1045275236' in a frame because it set 'X-Frame-Options' to 'SAMEORIGIN'.
Fair enough, I understand the same origin part of that problem, but wish it gave me the errors thru the callback - I have no intention of opening anything here - that's why I want to use a service account!
If I manually navigate to that URL I see the broken robot page,
That's an error
Error: invalid_client
no registered origin
Request Details
immediate=true
response_type=token
scope=https://www.googleapis.com/auth/gmail.readonly
redirect_uri=postmessage
proxy=oauth2relay869439690
state=1847286098|0.1045275236
origin=https://uvh02lohhb14dcmd9rb9buet1dr4b61j-a-gm-opensocial.googleusercontent.com
include_granted_scopes=true
hd=***********.co.uk
client_id=.apps.googleusercontent.com
hl=en
I don't think there's anything useful in there, just including it for completeness in showing what I've tried.
Any ideas on if this - is/should be/will be - possible, and if not any suggestions for other approaches to take?
I'm playing around with implementing a JavaScript server ping tool based on the accepted answer given on this question: Is it possible to ping a server from Javascript?. This essentially works by assuming the pinged server is down if no response has been given after n milliseconds.
That's great, and it's a pretty cool way of doing it, however there are two rather large pitfalls:
Not all servers do respond within the allocated time.
Sometimes an ERR_CONNECTION_TIMED_OUT error is thrown before our timeout timer has finished.
Both of these things cause incorrect results. The former suggests that the server is offline when it's possibly online and responding slowly, and the latter suggests the server is online when it's (likely) offline.
In an ideal world this code would capture what type of error thrown was thrown and handle this appropriately. After all, if the error thrown is a 404 Not Found error, this counter-intuitively means the server is online and has responded.
If we log the image error event, the only thing we see surrounding the error is:
Event {
...
type: "error"
}
There's no message or anything hinting at what the error thrown was, and both the 404 and ERR_CONNECTION_TIMED_OUT errors give identical information.
What can I do to capture the ERR_CONNECTION_TIMED_OUT error I see in Chrome's JavaScript console, rather than relying on a fixed-speed timer?
Update
The best way I can replicate this issue is by altering Trante's JSFiddle demo (as linked to in the question I've linked above) to use a 30000ms timer rather than a 1500ms timer:
this.timer = setTimeout(function () {
if (_that.inUse) {
_that.inUse = false;
_that.callback('timeout');
}
}, 30000);
The 'unknown' server should obviously not respond, but instead we see this:
In Chrome's console, the following error has been thrown:
Failed to load resource: net::ERR_NAME_NOT_RESOLVED
As the Image's onerror function has been fired with the generic error as given above, the function believes this to mean that 1. 'unknown' exists, and 2. it's online. The ERR_NAME_NOT_RESOLVED error appears to be something which only Chrome is aware of, and isn't passed through to the error event at all.
Update 2
Today I tried doing this with web sockets instead of images and unfortunately these suffer from the same problem. The only data surrounding the error returned is type: "error" - no information about what the error actually was.
I am starting to build/design a new single page web application and really wanted to primarily use client-side technology (HTML, CSS, JavaScript/CoffeScript) for the front-end while having a thin REST API back-end to serve data to the front-end. An issue that has come up is about the security of JavaScript. For example, there are going to be certain links and UI elements that will only be displayed depending on the roles and resources the user has attached to them. When the user logs in, it will make a REST call that will validate the credentials and then return back a json object that has all the permissions for that user which will be stored in a JavaScript object.
Lets take this piece of javascript:
// Generated by CoffeeScript 1.3.3
(function() {
var acl, permissions, root;
root = typeof exports !== "undefined" && exports !== null ? exports : this;
permissions = {
//data…
};
acl = {
hasPermission: function(resource, permission, instanceId) {
//code….
}
};
root.acl = acl;
}).call(this);
Now this code setup make sure even through the console, no one can modify the variable permissions. The issue here is that since this is a single page application, I might want to update the permissions without having to refresh the page (maybe they add a record that then needs to be added to thier permissions). The only way I can think of doing this is by adding something like
setPermission: function(resource, permission, instanceId){
//code…
}
to the acl object however if I do that, that mean someone in the browser console could also use that to add permissions to themself that they should not have. Is there any way to add code that can not be accessed from the browser console however can be accessed from code in the JavaScript files?
Now even if I could prevent the issue described above, I still have a bigger one. No matter what I am going to need to have the hasPermission functionality however when it is declared this way, I can in the browser console overwrite that method by just doing:
acl.hasPermission(resource, permission, instanceId){return true;}
and now I would be able to see everything. Is there anyway to define this method is such a way that a user can not override it (like marking it as final or something)?
Something to note is that every REST API call is also going to check the permissions too so even if they were to see something they should not, they would still not be able to do anything and the REST API would regret the request because of permissions issue. One suggestion has been made to generate the template on the server side however I really don't like that idea as it is creating a very strong coupling between the front-end and back-end technology stacks. If for example for whatever reason we need to move form PHP to Python or Ruby, if the templates are built on the client-side in JavaScript, I only have to re-build the REST API and all the front-end code can stay the same but that is not the case if I am generating templates on the server side.
Whatever you do: you have to check all the permissions on the server-side as well (in your REST backend, as you noted). No matter what hoops you jump through, someone will be able to make a REST call that they are not supposed to make.
This effectively makes your client-side security system an optimization: you try to display only allowed operations to the user and you try to avoid round-trips to the server to fetch what is allowed.
As such you don't really need to care if a user can "hack" it: if they break your application, they can keep both parts. Nothing wrong can happen, because the server won't let them execute an action that they are not authorized to.
However, I'd still write the client-side code in a way that it expect an "access denied" as a valid answer (and not necessary an exception). There are many reasons why that response might come: If the permissions of the logged-in user are changed while he has a browser open, then the security descriptions of the client no longer match the server and that situation should be handled gracefully (display "Sorry, this operation is not permitted" and reload the security descriptions, for example).
Don't ever trust Javascript code or the front-end in general. People can even modify the code before it reaches your browser (sniffers etc) and most variables are accessible and modifiable anyways... Trust me: you are never going to be safe on the front-end :)
Always check credentials on the server-side, never only on the front-end!
In modern browsers, you can use Object.freeze or Object.defineProperty to make sure the hasPermission method cannot be redefined.
I don't know yet how to overcome the problem with setPermission. Maybe it's best to just rely on the server-side security there, which as you said you have anyway.