I'm having an issue with the domain module. Currently, I'm trying to catch any uncaught errors that are thrown in a request. Using an express middleware and domains. All requests are routed through this function before calling next and moving on to it's proper route.
app.use (req, res, next) ->
domain = createDomain()
domain.on "error", (err) ->
res.send(500)
domain.dispose()
domain.enter()
next()
The problem is, how do I dispose of the domain if an error is never thrown?
I could hoist the domain and event outside the middlewear so I don't ever have to dispose, but then I won't have access to middlewear args that I need to send a 500.
Does anyone have a better solution to how I am handling this? I've spent way too much time trying to figure out a way (and many hacky ways) to handle this. Thanks.
You do not need to call domain.dispose() if no errors occurred. The purpose of domain.dispose() is to clean up any resources that were left in an indeterminate state after jumping out out the middle of the stack, and to squelch subsequent errors that would occur due to the bad state. The inverse call of domain.enter() is simply domain.exit().
That said, browsing through the code for domains, it looks like you don't want to use domain.enter/exit this way. Each domain.enter/exit corresponds to a stack push/pop of a shared array in the domain module code. So, for example, if a second request comes in before the first one has completed, and then the first one exits before the second one does, calling exit in the first domains handler will pop the domain for the second request. It seems quite likely that enter and exit should not be split across asynchronous things.
Have you tried simply using domain.run(next)? That seems to do the trick for me. It basically enters the domain for you and then calls the callback you give to it, and then immediately exits the domain after the callback returns. Any timers or event emitters created while you are in the domain will associate themselves with that domain, as well. Event emitters then also use a similar enter-call-exit pattern when calling event handlers. It appears in the code that it is not domains that track event handlers, but rather event handlers that track domains.
In short, don't try to pair an enter with a dispose, and don't try to use enter/exit across asynchronous boundaries. Use run/bind/add/remove.
Related
I have an express API with a bunch of routes.
routes.get('/', perms('read', 'document'), r(CRUD.getAll))
routes.get('/search', perms('read', 'document'), r(CRUD.search))
routes.get('/:id', perms('read', 'document'), r(CRUD.getById))
I made sure to have /search above /:id, however, when a new request comes in to /search, I see both endpoints getting a hit (I added a console.log inside of each function).
I tried flipping the two and in that case, only /:id gets a hit.
Any idea of why this may be happening?
Think about Express routing as an array of handlers (middlewares), that have a matching rule (url). When a request comes in, the router starts checking each item in the array from the beginning. If it matches the rule, then the handler is run (some don't have conditions, so they just run on each request :)). The request chain does not end when a single url is matched! You can execute multiple handlers on the same request (and that's exactly how middlewares work).
Therefore, it really depends on what happens inside your handler. You can tell it to continue with the next item in the list, and if there's a match - the next handler will be executed (like /search and /:id, which will be search again).
Make sure you end your response. Beware if you call next and with what parameters. Post some samples of the handlers in order to debug it more :)
I am looking for some advice on how to design the code to handle the fulfillment of requests sent by Dialogflow to my server. Dialogflow only lets setup a single webhook to handle all the intents. Let's say that I have 5 different intents; all of them will call the same webhook on my server. Now, how can I elegantly manage server-side different workflows depending on the intent?
The parameter that I would ideally use to make a distinction is contained in req.body.queryResult.intent.displayName; and indicates the name of the current intent. Right now I have two ideas, using express redirect method using the intent as part of the path, or creating a dictionary of handlers where the intents are the key.
Do you have any suggestions?
The dialogflow-fulfillment library, although deprecated, uses your latter approach - creating a Map from Intent name to Handler function and handing this map to a Dispatcher. It is a simple, straightforward, and speedy approach.
The multivocal library takes a similar, tho more expansive, approach, letting you register a handler against either the Intent name or the Action value assigned and having separate configurations for the response based on either Intent, Action, or another value that is set in the handler.
Redirecting to a new, path-based, method does not seem to give you anything.
Just want to say at the beginning. I'm really sorry if you will consider this as a duplicate but I'd like to ask you what is the middleware. I know stackoverflow has some similar questions but I'd be glad if you could answer this one. Also what is the .use ? Where do we use it? Thank you very much!
Middleware is a term that refers to request handlers that "pre-process" an incoming request. A given middleware will typically run on lots of incoming requests. Usually, it doesn't send the final response, it just does some setup or pre-processing on the request and then passes the request on to its eventual handler. There are thousands on things that people find to do with middleware.
The general idea is that it's easier to put middleware in one place and configure it to apply to lots of requests rather than have to add it to every single request handler that its supposed to apply to.
I'll offer a few examples:
Check to see if the requester is authenticated/loggedin on the site. If not, then redirect to the login page. If so, then pass the request through to the actual page request handler.
Log usage or performance statistics.
Pre-parse query parameters so they're already parsed for the request handler
Pre-parse post bodies so they're already parsed for the request handler
Preset desired cross origin headers for the response
Hopefully, you can see the general idea that middleware is often used as pre-setup work that can be done in one place rather than having to be added to every single request handler.
Keep in mind that middleware can be configured to determine which incoming requests it gets run for. It can be only for a single URL (not typical), a whole group of URLs such as everything start with a particular path, or all URLs on the entire site.
So, I have jquery plugins (or any other plugins / functions / libraries, for what matters).
I was wondering if I should call the plugin inside a try-catch in order to avoid aty undefined type errors, which may possibly block the execution of the rest of the script.
This is how/where I call the plugins right now.
(function($){
$(document).ready(function(){
// jquery plugin
try {
$("#app").plugin();
} catch (e) {
console.log(e);
}
// some other function applied to entire document
try {
libraryFunction();
} catch (e) {
console.log(e);
}
});
})(jQuery);
I know this is not code review, but if you have any suggestions on how to improve this code, please let me know.
I have dealt with scenarios when a plugin error actually screwed the rest of the script and using try-catch to call the plugin solved the problem.
Using try-catch a lot may slow down your script, but unless you're dealing with long loops, the performance change will be unnoticeable.
It is always a good practice to handle unknown behavior with a try-catch block. But even more important is to know how to handle the exception once its caught. In the above code, the exception is only being logged(which is good) and nothing else. In that case your execution may still get blocked.
Additionally, it would be good to also throw the exception back to the caller and make it handle the behavior. For example, in the above code, if jquery threw an exception, you may let the caller know about the exception and the caller may decide to call the function again or do something else.
In short, after catching, handling decides how your execution will recover. Logging alone will not help.
Edit:
An example to show why an exception should be thrown back:
Lets say I have an AppThread that requests a worker thread to store some data in an SQL database. Such a code flow will ideally not require the worker thread to return anything to the caller because the Worker Thread simply executes some Insert statements.
Now, during the insertion, worker thread caught an SQLException and simply logged and returned. Now the app Thread was never notified of this exception and it simply assumes that the data was inserted as requested. After sometime, the AppThread now wants to read the same data from the Database and asks the WorkerThread to fetch it using some Id. This time, the code will not throw any exception and the result set will simply be null. Now remember, the AppThread was sure that the data would be present and will not know what to do if the result set is null. So in one way, the code execution gets blocked after sometime of the exception.
Now, had the Worker Thread notified the exception to the App Thread earlier, the AppThread would have been aware and would have reattempted the insert operation or would show a dialog to the user letting her/him know that the data may need to be verified before attempting insert again. Also as the exception was passed back, its message would give more hints of what went wrong to the user directly. He will not have to go back to the logs to check what went wrong.
I'm a bit confused about node.js domains. I'm using them to catch errors that may be thrown in asynchronous code.
I'm not sure though, whether or not domains automatically clean themselves up for garbage collection once the domain.run(blah) has finished, or wether or not I have to manually call domain.dispose() once I am done with the domain?
The problem with domain.dispose() is that it also destroys all io streams that the domain may have been intercepting, which is not what I want as I'm just using this particular domain to just catch thrown errors in asynchronous code.
don't use it, it will be deprecated: https://github.com/joyent/node/issues/5018