Hey guys, I'm writing a library that will reside in the /lib folder that deals with processing a credit/debit card transaction.
I'm using the Forms framework to accept and validate the card details and then from my actions.class.php for that module, it instantiates my custom library that deals with the SOAP call to process the transaction.
My question is what is the best way to handle the potential errors, ie. setting up the SOAP call, processing the call, and then handling the response, which in terms of the transaction might be success or fail (with more information to feed back?).
I'm thinking something like a global error array and pre-defined error messages set in a config file somewhere. My actions.class.php ultimately receives a TRUE or FALSE, but if FALSE I need to inspect the error array and deal with it accordingly.
Any ideas?
Thank
What is the "place" that knows all about the potential errors? From your description I think it's the SOAP library. If it's your library, you should put the error codes there. Depending on how you show the errors to the user and if/how your app is localized, you then put the actual error messages (= what the user sees) where it makes the most sense.
If the SOAP lib is not yours then inspect the documentation and see what types of errors and error messages you may receive.
Related
I'm using Drupal 9, JSON:API module, Domain access module.
My task is to throw a custom exception when the request doesn't contain a specific parameter (domain-entity in my case).
For example - test-website.com/domain-parameter/jsonapi/some-entity
I need to throw a text "Please, specify domain-parameter to get correct data" if the domain-parameter is not specified in the URL above.
I've read a lot of articles about handling JSON API requests/altering JSON-API responses etc., but nothing helped me. I've found information that it's possible to achieve by writing a custom EventsSubscriber, but I'm not sure whether it's the best option.
Appreciate any help.
TLDR: Writing a service (in the model layer). It talks to ffmpeg. Where should validation go? Should I create a service response object so it is testable? How should it be structured?
Background: I'm designing some classes to retrieve data from an external service. It could be an API, but in fact it's calls to ffmpeg cli, which in effect is an API to the conversion tools themselves.
When talking to an external service, where the data retrieved may not always be the same, how is it best to go about maintaining at least a consistent application state on your end so your application doesn't depend on the external service to work?
I have already separated out the classes thus far, trying to maintain SRP within them:
class CommandDispatcher { }
The Command Dispatcher's sole job is to make a request for data (to ffmpeg) and retrieve the response for that data back.
class Converter { }
The converter's sole responsibility is to take user requests (like convert 1 to 2), and send the basics to the command dispatcher which handles the exec() calls.
Here are my questions:
When talking to an external API / service, should I be creating an APIRequest and an APIResponse object (in this case an FFmpegResponse object)?
I have seen examples of this for OAuth, where there is an OAuth response object. However, that's simple enough because calls to this are done over the HTTP protocol which tends to give back at minimum an error code and a message. Calls to something like ffmpeg don't guarantee a similar response (ffmpeg may not be installed, for example). Is this object merely a domain object (i.e. an entity: some class members and setters and getters)?
Validation. If I am creating an FFmpegResponse object, whose job is it to put the data into the right members of the Response object?
Imagine ffmpeg isn't installed and the CommandDispatcher gets the response back empty. Is it up to the CommandDispatcher to then populate the FFmpegResponse object with an "ffmpeg not installed" error? Should I have a validation object do this?
Remember, I'm trying to stick to the Single Responsibility Principle here, so I'm thinking that the CommandDispatcher shouldn't care about whether the data is valid or not - it should merely ask for data and retrieve it. Where does my validation fit within the model layer for this service?
This isn't only for FFmpeg but will help for future external service calls. What is the best [practice] way to structure your code and classes to maintain SRP yet also a consistent application state regardless of whether or not the external service responds in an expected way?
In your current structure, CommandDispatcher should be either an interface or an abstract class (depending on the necessity of abstract code). You would then create a concrete implementation: FFMpegCommandDispatcher which would encapsulate the understanding of ffmpeg specific responses.
Response objects will then take on a similar structure: CommandResponse would be an abstraction with the concrete implementation FFMpegCommandResponse.
It would be best to create a set of common error conditions (serviceNotAvailable, serviceNotInstalled, serviceDiedAHorribleAndBloodyDeath, etc). Your dispatcher implementation can then set a common error code on the response object and provider implementation specific details. ('Error 1984: FFMpeg is watching you')
If you're concerned (and I would be) about validating input as well. You could create a CommandRequest abstraction, and FFMpegRequest implementation, that will take user input and make sure that it's okay to be sent to the command line.
As shown in the php documentation is it possible to create your own exception handler. I see this as a reasonable way to handle my user generated errors and exceptions throughout the project I am working on. Through research I have made a decent amount of progress in implementing a specific one, just for one class, including things like using ErrorException (from the first answer) and making sure to return false for error levels that I can't handle.
I have however run into a wall with making it more generic. I don't want to have to write a separate handler for every class I write (especially because the vast majority of that code is going to be the same for every one). Yet it feels like terribly bad practice to have every single error for the entire project in the same handler.
The closest I have gotten to what feels like an acceptable solution is to write a subclass of ErrorException for every class I want to handle the errors for and store messages in each of those. But even with this I am probably going about it wrong (I don't think that would be the proper place to store default error messages). Is there a universally accepted way of doing this that I have been unable to find? or is one of these ways actually the way it's generally done? or are there multiple solutions that are scalable based on the size of the project?
EDIT: Just realized I can write a generic Exception_Handler with the reused code and extend it for each set of errors I have (real herp moment for me), but it still seems like I should handle all errors in the same place. If I'm completely wrong, let me know.
EDIT 2: Decided to go with a config file containing the error messages for each class that will throw errors, then the name of the class that throws the error defines what config file is loaded to get the list of messages associated with error number. This also allows me to easily define messages that should get logged as opposed to messages that should get sent to the user (essentially specific vs. generic messages).
I guess I'll mark this as answered or something, but if I'm doing something wrong feel free to let me know, help is always appreciated.
Decided to go with a config file containing the error messages for each class that will throw errors, then the name of the class that throws the error defines what config file is loaded to get the list of messages associated with error number. This also allows me to easily define messages that should get logged as opposed to messages that should get sent to the user (essentially specific vs. generic messages).
More specifically I'll probably use an ini file that defines an array of arrays where each number contains the array of error messages for that error number. Then use a foreach with the thrown error numbers to return the error message(s).
I have a question regarding error handling in Zend. I am fairly new to zend frame work.
I am new on this project that i am working on and the previous developers didn't handle service errors and the application is fairly large so I am trying to figure out an easy way to handle all the errors the service returns, and even handle the errors when service fails.
so when ever there is an error we need to alert the user that something is wrong and show the error.
now since i will be getting that in Model, how do I handle this in elegant way so that there is not much rework to be done.
Can i create a common class and extend it? I also need to alert the user in case of any error.
I want a better way because I have more than 150 controller files and about more than 100 model files.
Thanks
For a ZF app that's using Zend_Application, you should ensure that your application.ini file has this in it:
resources.frontController.throwExceptions = false
Then any Exception that is thrown will be trapped and the ErrorController's errorAction() method will be called. This gives you a centralised place to handle errors.
I have a problem with the error page 500 of symfony (apps/%app-name%/config/error/error.html.php).
I had to learn that symfony skip the standard way of page creation completely. I had to organize all the helpers myselve.
require_once dirname(__FILE__) . '/../../../../lib/vendor/symfony/lib/helper/HelperHelper.php';
use_helper('Tag', 'Asset', 'Url', 'I18N', 'Date', 'Partial');
But now I am missing the contents of the configuration. How can I manually trigger the autoloader mechanism, so that I get the information from view.yml and so on?
I don't know if it's smart to depend on the whole Symfony stack when you're displaying an error.
IMHO the error pages need to be designed as light-weight as possible, 99% static HTML, with only some php code to display a friendly error message.
Because, what if something is wrong with your Symfony stack, then you can't even present a decent error page to the user.
The 500 error page is also a "hard fail" page, it is the most generic error handler which is only shown if no action tried to catch the exception.
In the cases where you want to use the view and everything, I think it's better to catch the exceptions right there in the action, and present better error pages (return sfView::ERROR) with information the user can act on.