Web Api 2 all errors logging - asp.net-web-api

Some errors get uncaptured (like ModelBinding exceptions or route change failure exceptions) when I use ExceptionLogger and ExceptionHandler implementations.
The question is how to log all exceptions fired in Web Api 2 app?
Btw, I use OWIN to host it.

What about a catch-all middleware?
app.Use(async (context, next) =>
{
try
{
await next();
}
catch (Exception ex)
{
// log
}
});

Related

(VueJS, Axios) Different way to catch errors

I'm currently building a single page application based on Laravel and VueJS.
Is there any better way then mine to handle errors with axios?
This is how I currently do it when a user clicks on login button:
VueTemplae:
methods : {
authenticateUser() {
axios.post('/api/login', this.form).then(() => {
this.$router.push({name : 'home'});
}).catch((error) => {
this.error = error.response.data.message;
});
}
}
Api route:
public function login() {
try {
// do validation
} catch(Exception) {
// validation failed
throw new Exception('login.failed');
}
// manually authentication
if(Auth::attempt(request()->only('email', 'password'))) {
return response()->json(Auth::user(), 200);
}
// something else went wrong
throw new Exception('login.failed');
}
Unfortunately, throwing an exception always prints an internal server error into the console.
If I return something else than an exception, axios always executes then().
Is there any way to prevent this or a better way to handle axios responses?
Thank you!
Your API needs to return a response with a 4XX status code in order for the catch block to fire in your Vue component.
Example:
After you catch the error on the API side, send a response with status code 400 Bad Request. It will be formatted similarly to your successful login response, but with an error message and 400 status code instead of 200.

Sails.js: applying session and token authentication policies simultaniously

I am developing an application with sails.js. For the web application I use session authentication with passport. Now I also need to make my server accessibe from a mobile application, which requires token authentication. My question is the following: how can I define the policies so that sails accept SessionAuth or TokenAuth for certain routes?
The way sails handles policies, they are all applied one after another using AND logic. There is no way to combine them logically in other ways, like OR or more complicated combinations.
In your case, I would expect it would be fairly easy to write a third policy that handles the "SessionAuth or TokenAuth" all in one policy. Say you have existing SessionAuth.js and TokenAuth.js policies that look like this:
module.exports = function(req, res, next) {
if (req.isSessionAuthorized()) {
return next();
}
// handle rejected request
};
, and,
module.exports = function(req, res, next) {
if (req.isTokenAuthorized()) {
return next();
}
// handle rejected request
};
Then you just create a third policy called SessionOrTokenAuth.js:
module.exports = function(req, res, next) {
if (req.isSessionAuthorized() || req.isTokenAuthorized()) {
return next();
}
// handle rejected request
};
Then apply the newly created policy to the desired controller endpoints in /config/policies.js:
SomeController: {
'*': true,
'sessionOnlyEndpoint': ['SessionAuth'],
'tokenOnlyEndpoint': ['TokenAuth'],
'anyAuthEndpoint': ['SessionOrTokenAuth'],
}
The actual checks are likely a touch more complicated, but probably not by much. Hope this helps.

Monolog with Bot Framework

We are using the Microsoft Bot Framework for our chat bot. Our Message Controller is standard :
public async Task<HttpResponseMessage> Post([FromBody] Activity activity)
{
HttpResponseMessage response;
try
{
if (activity.Type == ActivityTypes.Message)
{
//do some stuff
await Conversation.SendAsync(activity, () => new RootDialog());
}
else
{
HandleSystemMessage(activity);
}
response = this.Request.CreateResponse(HttpStatusCode.OK);
}
catch (Exception ex)
{
//do some catching
}
return response;
}
Sometimes, the bot needs to have long monologs. If it takes too long, we receive a 502 Bad Gateway error.
Any solution for that ?
Bot Framework calls time out after 15 seconds. Your bot must return a successful HTTP status code within 15 seconds for Direct Line to consider the message successfully sent.
If your bot does a lot of offline work or sends multiple messages, you should move that work to a background thread so the incoming request completes within 15 seconds.
Here's a snippet that correctly handles loads hosted inside ASP.Net and other hosting environments.
if (HostingEnvironment.IsHosted)
{
HostingEnvironment.QueueBackgroundWorkItem(c => DoWorkAsync());
}
else
{
Task.Run(() => DoWorkAsync());
}
...
private async Task DoWorkAsync()
{
// do some stuff
}
Task.Run is simpler but HostingEnvironment.QueueBackgroundWorkItem prevents ASP.Net from tearing down your process before this work is complete.

ASP.NET Core 1.0 WebSocket Setup?

I'm struggling to find an example to setup WebSockets in ASP.NET Core 1.0; they all seem to be for the previous versions of ASP.NET and some rely on properties that don't seem to exist under context (for me).
Main documentation only has a placeholder too. http://docs.asp.net/en/latest/
For example:
app.UseWebSockets();
app.Use(async (context, next) =>
{
if (context.IsWebSocketRequest)
{
WebSocket webSocket = await context.AcceptWebSocketAsync();
await EchoWebSocket(webSocket);
}
else
{
await next();
}
});
Doesn't work because IsWebSocketRequest doesn't exist now. What is the correct approach in ASP.NET Core 1.0?
After some disassembly it looks like its been moved around a little; and there is a new WebSocketManager
app.UseWebSockets();
app.Use(async (context, next) =>
{
var http = (HttpContext) context;
if (http.WebSockets.IsWebSocketRequest)
{
WebSocket webSocket = await http.WebSockets.AcceptWebSocketAsync();
}
});
Also turns out that because there was a compile error, it assumed context was of type RequestDelegate. After fixing the usage to context.WebSockets.IsWebSocketRequest it now knows that context is HttpContext

How to use Passport-Facebook login without redirection?

I'm building a phonegap application which will have nodejs at the server side. I wanted to implement login using passport-facebook strategy but their callbacks specify two routes, /successcallback and /failurecallback. Having a single page application, this makes it very confusing to have users redirected to so and so page.
I don't want to serve static files (index.html, login.html) from the server but rather have them on the client and ask the client to make ajax calls. So far, I'm able to make /auth/facebook call as an AJAX request but I can't receive any response on the same request because the login strategy requires the user to be redirected. I'd rather want to send a user_id or name back to the user on successful login or show him the login form (which is also on the www directory in phonegap) on failure. But the redirection and CORS errors are preventing me from doing this. Is there any way I can implement this? I've looked for this since a few weeks now, but no success. I'd really appreciate your help!
PS: I'd rather avoid having to send all html and static content from the node server.
EDIT: Adding login code for better understanding:
app.get('/userpage', utility.isLoggedIn, function(req, res)
{
res.send('User:'+req.user);
});
app.get('/', utility.isLoggedIn, function(req, res)
{
res.redirect('/userpage');
});
app.get('/auth/facebook', passport.authenticate('facebook'));
app.get('/auth/facebook/callback',passport.authenticate('facebook',
{
successRedirect : '/',
failureRedirect : '/login'
}));
app.get('/logout', function(req, res)
{
req.logout();
res.redirect('/login');
});
utility.isLoggedIn:
function isLoggedIn(req, res, next)
{
if (req.isAuthenticated())
return next();
res.redirect('/login');
}
You can't do that with facebook oAuth, but Facebook provides another login solution where you can code your client app to request a token, that you can later validate on the server with passport-facebook-token.
This way you can use the advantages of passport for persistent sessions, without that annoying redirection.
Instead of using the standard redirections offered by passport, you can define your own function which will be executed instead of the redirection. Here's an example of what that code would look like
passport.authenticate('login', function(err, user, info) {
if (err) { return next(err); }
if (!user) { return res.json({ status:"failed", "error": "Invalid credentials" }); }
// req / res held in closure
req.logIn(user, function(err) {
if (err) { return next(err); }
return res.json({ "status":"success"});
})
})(req, res, next);

Resources