Do we need to use error handler middleware in ExpressJS for RestAPI? - express

I know that the error handler middleware is like the final person who gives a very generic message to the user when things get wrong. Like return 500 server error.
But I think it's not helpful for the user. Once we catch an error in routes or middleware, it's better to give the user a more specific error message for a certain error.
So I don't think we should use error handler middleware in this case then? Am I right?

you can override the default error handler to give your users more specific error messages defined by you in your own custom error class
const { CustomAPIError } = require('../errors/customErrors');
const errorHandler = (error, req, res, next) => {
// for debugging purposes
console.log('[ERROR]: ', error);
if (error instanceof CustomAPIError)
return res.status(error.statusCode).json({message: error.message});
res.status(500).json({message: "Internal Server Error"});
}
module.exports = errorHandler;

Related

Retrieving UpstreamPathTemplate at runtime Ocelot Gateway

I would like to retrieve the "UpstreamPathTemplate" parameter at run time, to use in my Logs. Does anyone know how to do this, please?
You can use some middleware in the OcelotPipelineConfiguration and access the route in the context.
Something like that:
{
//PreQueryStringBuilderMiddleware occurs after authorization
PreQueryStringBuilderMiddleware = async (ctx, next) =>
{
var upstreamRoute = ctx.DownstreamReRoute.UpstreamPathTemplate;
Log.Information($"{upstreamRoute}");
await next.Invoke();
}
};
Or implement your own ASP.NET middleware, catch all requests and log or whatever you want.

Aurelia cancel a specific request

Is there a way to cancel a specific request? I followed this to cancel request, but what if i have more than one request, how can i be sure that im not canceling the wrong request? Is there a way to cancel a specific request?
Currently it works like this:
async getEmployeeListBySearchword(searchword: string): Promise<IMember[]> {
try {
const response = await this.get(`employees/${decodeURIComponent(searchword)}`);
return JSON.parse(response['response']) as Promise<IMember[]>;
}catch(e){
if(e.responseType != "abort") {
console.log(e);
}
}
}
cancelRequest(){
if(AbortableHttpService.http){
AbortableHttpService.http['pendingRequests'].forEach(request =>{
request.abort();
});
}
}
The http setup code is wrapped into a class named AbortableHttpService, it creates the HttpClient and configures it and hides some of the boilerplate code for it.
I'm not sure if this is documented or not, but in the aurelia-http-client source code, I see that a cancel/abort function is added to the promise you receive when making a request.
So calling either response.cancel() or response.abort() should work.

Parse-Server capture bad session token requests

Is there any way to capture bad session token requests on a remote parse-server app?
Unfortunately, verbose logs for bad session tokens only display a very not verbose error message that an invalid session token was used, whereas all other requests will display the full headers used to make a request. I need to get to those headers so I can identify the x-parse-session-token being sent.
I've discovered I can add some middleware doing something like this:
var myMiddleware = function (req, res, next) {
// extract request headers
next()
}
app.use(myMiddleware)
But I wouldn't yet know if the session token was valid or not at that point, and I don't think it'd be efficient to set up a whole extra middleware checking the validity of every session token that gets passed in.
Any tips on how I could get access to these x-parse-session-token headers for requests that are failing due to bad session tokens would be greatly appreciated.
One hacky way would be to override in your middleware the req.json call.
const myMiddleware = function (req, res, next) {
const json = res.json;
res.json = function(object) {
if (object.code == Parse.Error.INVALID_SESSION_TOKEN) {
// get the session token
const token = req.headers['x-parse-session-token'];
// Invalid token, do something
}
// Forward the response
json.call(res, object);
}
next()
}
server = new ParseServer({
applicationId: YOUR_APP_ID,
/* more options */
middleware: myMiddleware
});
// continue initialization here
This should do the trick what do you think?

Custom Failure Handler for withFailureHandler - Google Apps Script

I'm trying to get more information for when google.script.run fails. I know that I can get a basic error handling callback function to give me the error message with something like this:
google.script.run.withFailureHandler(handleError).getMe();
Where handleError gets an argument passed in for the error message.
function handleError(error) {
console.log(error);
}
However, if I wanted to created a custom error handler that provided the location of where the exception was being thrown, I could use a custom function on withFailureHandler, like this:
google.script.run.withFailureHandler(function () {
showError(error, 'getMe');
}).getMe();
With this method I'm stumped with one issue. How do I capture the error message to pass to my showError() error handler?
Simply add the error parameter to your anonymous function.
google.script.run.withFailureHandler(function (error) {
showError(error, 'getMe');
}).getMe();
An errorHandler receives the error event from an exception that's thrown on the server. To pass a custom message, have your server side code do something like this:
...
if (errDetected) {
throw new error("Custom message")
}
...

FOSRestBundle: Returning JSON/XML meta data for "Bad Credentials" Exception

I'm using FOSRestBundle for my REST API and so far it has been a great tool. I use HTTP Basic Auth and in most of the cases it works just fine. However, I have problems with the bundle's exception behaviour when bad credentials are submitted. When handling exceptions (via the integrated authentication handlers or the exception mapping configuration), the bundle always gives me a response with the correct HTTP status and JSON/XML content similar to this:
{
"code": 401,
"message": "You are not authenticated"
}
This is fine, it also works when no authentication information is submitted at all. However, when submitting bad credentials (e.g. unknown username or incorrect password) I get the HTTP code 401 Bad credentials (which is fine) with an empty message body. Instead, I would have expected something similar to the JSON above.
Is it a bug or a configuration issue on my side? I would also love to know how these kinds of authentication errors are exactly handled by the bundle, since overriding the BadCredentialsException's status code in the codes section of the bundle's exception configuration section seems to be ignored.
Thanks!
Alright, after digging into the bundle's code some more, I figured it out. The problem results from the way bad credentials are handled by Symfony's HTTP Basic Authentication impementation. The 401 Bad Credentials response is a custom response created by BasicAuthenticationEntryPoint, which is called by the BasicAuthenticationListener's handle function, immediately after an AuthenticationException has been thrown in the same function. So there is no way of catching this exception with a listener:
public function handle(GetResponseEvent $event)
{
$request = $event->getRequest();
if (false === $username = $request->headers->get('PHP_AUTH_USER', false)) {
return;
}
if (null !== $token = $this->securityContext->getToken()) {
if ($token instanceof UsernamePasswordToken && $token->isAuthenticated() && $token->getUsername() === $username) {
return;
}
}
if (null !== $this->logger) {
$this->logger->info(sprintf('Basic Authentication Authorization header found for user "%s"', $username));
}
try {
$token = $this->authenticationManager->authenticate(new UsernamePasswordToken($username, $request->headers->get('PHP_AUTH_PW'), $this->providerKey));
$this->securityContext->setToken($token);
} catch (AuthenticationException $failed) {
$this->securityContext->setToken(null);
if (null !== $this->logger) {
$this->logger->info(sprintf('Authentication request failed for user "%s": %s', $username, $failed->getMessage()));
}
if ($this->ignoreFailure) {
return;
}
$event->setResponse($this->authenticationEntryPoint->start($request, $failed));
}
}
The entry point's start function creates the custom response, with no exceptions involved:
public function start(Request $request, AuthenticationException $authException = null)
{
$response = new Response();
$response->headers->set('WWW-Authenticate', sprintf('Basic realm="%s"', $this->realmName));
$response->setStatusCode(401, $authException ? $authException->getMessage() : null);
return $response;
}
The fist if-clause in the handle function above also explains why it works in the case of "no user credentials at all", since in that case, the listener just stops trying to authenticate the user, and therefore an exception will be thrown by Symfony's firewall listeners (not quite sure where exactly), so FOSRestBundle's AccessDeniedListener is able to catch the AuthenticationException and do its thing.
You can extend AccessDeniedListener and tell FOSRestBundle to use your own listener with the parameter %fos_rest.access_denied_listener.class%. (service definition)
parameters:
fos_rest.access_denied_listener.class: Your\Namespace\For\AccessDeniedListener
Then add an additional check for BadCredentialsException and emmit an HttpException with the desired code/message similar to the check for AuthenticationException at Line 70.