I would like to somehow apply a try catch statement to all Actions as a backstop for any uncaught exceptions.
I think this would be particularly helpful for Ajax Actions, because the catch statement could send back a default 4xx status code. Prototype's onFailure() function could then do the client-side error handling.
How can I do this without wrapping the Action call with a try/catch in the cake dispatcher like this:
try {
output = $controller->dispatchMethod($params['action'], $params['pass']);
}
catch {...}
Does anybody have a suggestion or another workable strategy for gaining this functionality without touching the dispatcher?
How do people feel about putting exception handling in the Displatcher? I imagine when cake drops php 4 support, there will be a built-in mechanism for this.
[Edit] I've looked into the cake Error Handling. Without try/catch it seems like there is a big loss in functionality. And, I am hesitant to mix cakeErrors and other Exceptions.
In app/webroot/index.php replace the line
$Dispatcher->dispatch($url);
with
try {
$Dispatcher->dispatch($url);
} catch(Exception $e) {
// do exception handling
}
I'm not too sure why you would want to do this. You can check the params to see if it's an ajax call in the controller using,
if($this->params['requested'])
I don't know what kinds of exceptions your application might create, but if it's a missing action, view or similar, Cake will output an error page, which you can customise in the app/views/errors folder.
The book has some information on how to handle errors using CakePHP's built in error handler here, http://book.cakephp.org/2.0/en/development/errors.html
You could also have a Google around for articles and tutorials on creating your own custom error handler, or extending the built in one, so that it wraps all dispatch calls in a try{}catch{} from the core of the dispatch cycle.
Related
I am building a React app (with react-redux, redux-saga, and axios), and
I need advice on how to arrange my project for displaying user-friendly error messages.
(It is up to me to decide what and how I display to the user)
In particular, I would like to get answers to the following questions:
Should I display a message based on the status code?
Should I break down the errors to client / server / other errors and what are the benefits of that? (based on example from Axios)
Where should I keep the error messages, in the component itself, in a config file (I would like to see an example of such a file)?
How would my redux state tree look?
Should I dispatch an action for every error based on the status code?
I would appreciate any suggestions or real-world examples.
Here are some examples of error responses from our backend:
Request URL: https://example.com/api/call/123
Request Method: POST
Status Code: 400 Bad Request
Request URL: https://example.com/api/call/123
Request Method: PUT
Status Code: 409 Conflict
Request URL: https://example.com/api/user/me/
Request Method: GET
Status Code: 401 Unauthorized
It basically depends on what method you are trying to display the message, For instance, in our own projects, We are using a global snack bar component to display errors if any have occurred during the requests.
Most of the time users don't care about the status code, if you want not to be very specific then you can display a simple alert/snack bar for example: "Sorry, Some error occurred".
If you are sure that you do need to show specific errors to the user the I definitely recommend a constant file for errors which will store all your error message, You can keep them in constants directory in the store folder so maybe even in /helpers, It depends on your choice.
Yep, you can definitely divide your errors based on if the error was on the server or the client-side.
I don't think the redux tree will change if you're not managing errors in the tree. If you want to, definitely use a snack bar/alert reducer on the top of the tree
You may not want to show the same error for a status code in each of different components, Otherwise, if you want to, You can use it but that would add a lot of unnecessary code into your requests.
For our projects, since we are using i18 for internationalization, We have a snack bar reducer and the action folder, We import the snack bar actions in our sagas and just display a simple error message ( You definitely can customize it for your needs accordingly), That's all,Keep it simple.
yield put(Actions.apiRequest);
try {
const res = yield axios.put('/todo/', updateData);
if (res.data.status === 'success') {
yield put(Actions.fetchTodos(todoID));
yield put(snackbarSuccess('Todo Saved Successfully !'));
} else {
throw new Error();
}
} catch (error) {
yield put(Actions.apiError);
yield put(snackbarError(REQUEST_FAIL)); // an imported constant
}
Some basic code behind my implementation.
1) Assuming you're also doing the BE or can ask someone to adjust the response - It might be best to return a body with your API error response, and avoid just HTTP status codes - if possible. That could then contain an error 'code' that maps to a message on your front-end, as well as field name which can be really helpful for displaying errors in the right place on forms, etc. alternatively, the entire message could come from the BE and the FE simply display it. I work on an enterprise-level codebase that uses both these methods.
2) Regarding error message, i'd always store them in a common file but beyond that up to you really. It sort of depends on how you implement #1. Personally I like error 'codes' stored in an enum file, which correspond to a message because you can then do other logic from that (e.g. don't display the rest of a form if error X is triggered, use a custom message for the error code in one situation or fall back to a default
3) Not sure - I guess you'd do that if you want to log server-side errors but show client. Where I work we differentiate purely for different logging categories I think.
4) Again depends on your implementation - somewhat up to you. Some form packages will handle this for you in redux. Others will just use local state and not redux for this.
5) Would make sense to, yes. Again if you look a custom error code returned in the body of the API call that'll give you more flexibility.
I hope that gives you some ideas, based on my experience rather than any set way of thinking.
have a look at https://reactjs.org/docs/error-boundaries.html as well, and if you haven't already REST APIS / best practice for REST API: https://blog.restcase.com/rest-api-error-codes-101/
One of the requirements of the project I am working on is that I log the connections made to the site, due to the amount of processing being done to get as much information as possible I would like to process this after the page has been sent back to the user.
At the moment I am running my code in the afterFilter of my appController:
public function afterFilter(Event $event){
$log_request = new RequestsController;
$log_request->log_request();
}
I am attempting to run this in afterRender of my appController:
public function afterRender(Event $event, $viewFile){
$log_request = new RequestsController;
$log_request->log_request();
}
But I can not seem to get the code to execute or if it does then I do not know how to find out what the error being thrown is.
If somebody can point me towards an example of this being done or a concurrent method of doing this (it needs to be logged within a second of the request) I would appreciate it.
$log_request = new RequestsController; you don't instantiate controllers inside controllers. You want to learn the MVC design pattern first when using a MVC based framework or you'll end up with a non maintainable piece of horrible spaghetti code. I recommend you to do the blog tutorial to get a basic understanding.
If somebody can point me towards an example of this being done or a concurrent method of doing this (it needs to be logged within a second of the request) I would appreciate it.
Read this chapter: CakePHP Logging Taken from there:
Logging data in CakePHP is easy - the log() function is provided by the LogTrait, which is the common ancestor for many CakePHP classes. If the context is a CakePHP class (Controller, Component, View,...), you can log your data. You can also use Log::write() directly.
Add the log trait to the AppController, pass the request to the log() method and configure the logging to log these requests to whatever you prefer either in afterRender() or if you want to do it really late, do it in __destruct().
I'm using JDO for data storage in a Play 2.1 Scala project. Ideally, I'd like each request to have its own transaction, committing when it's finished, and rolling back if something goes wrong.
The best way I can figure out to do this is with Action Composition, where I create my own Action-like object that starts the transaction, wraps the block of code in an Action, evaluates it and saves the result, commits or rolls back the transaction, and then returns the result.
The only thing that concerns me about this is that my whole project now consists of DbActions instead of regular Actions. I'm not sure why this concerns me, except that I think there must be a better place to do this. However, when I check the hooks available in GlobalSettings, nothing looks like it would work.
Should I just go with DbAction and stop second-guessing myself, or is there a place to hook this behavior in so that I can just use Action?
Todd
I don't if it is a better alternative, but you could also use Action Composition instead of creating a subclass via inheritance.
Basically, you could write something like this:
def TransactionalAction(f: Request[AnyContent] => Result): Action[AnyContent] = {
Action { request =>
startTransaction
try {
f(request)
commit
} catch {
case e: Exception => rollback
}
}
}
and then use:
def index = TransactionalAction { request =>
val something = someQueriesInDB
Ok(something)
}
I'm not sure that there is a best practice for this yet. I look forward to reading other people's answers.
This page should show you how to do what you want to do. Basically in Global you either extend WithFilters or override doFilter. You're still just wrapping the Action, but you're doing it from a central place.
Now, whether or not this is a better idea than doing the action compsoition as suggested here, I don't know.
If a module requires a claim, and the user does not have the claim a 403 response is returned.
eg:
this.RequiresClaims(new[] { "SuperSecure" });
or
this.RequiresValidatedClaims(c => c.Contains("SuperSecure"));
but that just returns a blank page to the user.
How do I deal with a user not having the required claim?
Can I 'catch' the 403 and redirect?
The RequiresClaims method returns void or uses the pre-request hook to throw back a HttpStatusCode.Forbidden. What should I do so the user knows what has happened?
Many Thanks,
Neil
You can catch it either by writing your own post request hook (either at the app level, or the module level) or by implementing your own IErrorHandler, probably wrapping the default one.
The error handler stuff is going to change so you will be able to register multiple ones (for different error codes), it's setup to do that (with the "can/do" interface) but for some reason my brain didn't add it as a collection :-)
The silverlight object tag accept an 'onerror' parameter which calls back to a piece of javascript of your choice. The default implementation which is generated by the Visual Studio template assembles a descriptive message and throw it as an Error (which lets e.g. IE display the little warning triangle).
It seems to me that each time this callback is fired our silverlight instance is dead and you need to refresh the page. Is this a reasonable deduction?
Another issue is how to best handle this callback. Showing the little warning icon is somewhat developer-centric and it doesn't allow us (the developers) to discover what is actually failing in production when it is run on a customer machine. What are people doing with this? A couple of our own (more or less concrete) ideas are:
Send the error message back to the server via some exposed endpoint
Remove hide the silverlight object, show a nicer and more descriptive message to the user and a 'refresh' link to start up the silverlight page again (we run a full-sized silverlight application so if the silverlight object isn't working, the customer might as well reload anyway)
Somehow reload the object tag automatically to avoid having the customer perform any actions to get going again (perhaps combined with some notice to the customer that the 'system' restarted)
Ideas, thoughts, best practices, anti-patterns? What are you guys doing (except ensuring that the silverlight app never fails, but that's another discussion)?
I like a nice error reporting in the form of a "form" using SilverlightFX grab the source http://github.com/NikhilK/silverlightfx/tree/master , check it out very cool framework otherwise basically would be just a summary of the error, the ability to send it via upload that emails to support and an "oops we goofed" title :) I handle all unhandled expetions in this way, there is also a nice article on handling the errors by type using a dictionary
http://www.netfxharmonics.com/2009/04/Exception-Handlers-for-Silverlight-20 also a favorite of mine
. Hope this helps
I recommend you change how you're instantiating the Silverlight control. Instead of using the object tag, you can call Silverlight.CreateObjectEx() in the Silverlight.js file. This is probably a little more natural for your scenario. If it fails, you can call it again which is simpler than trying to reload object tags. Ex:
Silverlight.createObjectEx(
{
source: '/../VideoPlayer.xap',
parentElement: document.getElementById('movieplayerDiv'),
id: 'VideoPlayer',
properties: {
width: '100%',
height: '100%',
background: '#FFd9e3d7',
inplaceInstallPrompt: false,
isWindowless: 'false',
version: '2.0'
},
events: {
onError: onSLError,
onLoad: onSLLoad
},
initParams: "...",
context: null
});
function onSLLoad(sender, args) {
}
function onSLError(sender, args) {
// alert('error');
}
Other thoughts:
If your javascript error handler fires, the instantiation has failed. Silverlight will not suddenly come back to life by itself. Instead, call CreateObjectEx to give it another shot ;)
There are 2 kinds of terminal errors in Silverlight. 1) Managed errors (hit the managed Application_UnhandledException method). Note that some errors may not even get to this point. If the managed infrastructure can't be loaded for some reason (out of memory error maybe...), you won't get this kind of error. Still, if you can get it, you can use a web service (or the CLOG project) to communicate it back to the server. 2) Javascript errors. These are what you're getting right now. I recommend bouncing these back to your server with JQuery (or Javascript library of preference). Something like:
$.post(this.href, { func: "countVote" },
function(data) {...}
How you handle this on the server, of course, is dependent on what your server stack looks like. It's super easy in MVC, btw.