How to document asynchronous results, exceptions? - asynchronous

Javadoc has clear rules for documenting the return value and exceptions thrown by a method. But what are we supposed to do for methods that return/throw from within an asynchronous response such as CompletionStage or Future?
If I use #throws to document exceptions that are thrown asynchronously, the IDE complains that the method doesn't throw the exceptions (directly). And it is right, the method does not.
If I document the long list of exceptions that are thrown asynchronously in the #return section the resulting documentation is difficult to read.
What is the best practice for this situation? If possible, please reference established libraries as examples.

For what it's worth, I'm currently using the following syntax but I don't think it is an established best practice:
/**
* #param symbol the name of a stock ticker
* #return the price of the ticker
* <br> {#code #throws NullPointerException} if {#code symbol} is null
* <br> {#code #throws IOException} if an I/O error occurs
*/
public CompletionStage<BigDecimal> getPrice(String symbol);
My guidelines are as follows:
Throw all exceptions asynchronously, even for instant failures like argument preconditions. This allows clients to centralize error handling in one place.
Document exceptions under the #return using the same #throws syntax that is familiar to developers.
The result looks quite decent.

Related

symfony2 phpStorm autocomplete code, comments, best practices

i may have little be too general questions and if there are i am sorry for duplicates. (did not found the answer i was looking for).
First of all i am using symfony2 framework for developing and i am thinking about purchasing phpStorm. Its not a cheap program and i dont want to waste money. But i like it to now so i would like to ask if its a good step to future?
And my second and the main question
Sometimes happens i dont see auto-completed suggestions of methods of some objects...
Is there any way or some good practises i can do to help phpStorm understand with what object i am dealing with?
I have on my mind things like i saw in the code of someone else:
public function updateSomething(User $user
Or...
/**
* Draws an arc on a starting at a given x, y coordinates under a given
* start and end angles
*
* #param Imagine\Image\PointInterface $center
* #param Imagine\Image\BoxInterface $size
* #param integer $start
* #param integer $end
* #param Imagine\Image\Color $color
* #param integer $thickness
*
* #throws Imagine\Exception\RuntimeException
*
* #return DrawerInterface
*/
Do these things help and I should write them or there are just for better "user-read ability"?
Your first question is of a type that normally belongs outside of StackOverflow as its very subjective, there isn't really an answer, only people's opinions. For what it's worth, in my opinion PHPStorm is worth every penny compared to either a) using no IDE / a text editor, b) using the free Aptana IDE (eclipse based) which are the alternatives I tried before PHPStorm. For me there there are numerous productivity savings but one invaluable feature is the debugger which just works (once you have XDebug configured with PHP).
To answer your second question about the auto-completion of methods of some objects - Yes, both the examples you gave help and those along with additional use of PHPDoc comments should enable the PHPStorm method auto-completion to work in almost all cases. This should also have the side-effect of clearing out most of the spurious PHPStorm yellow highlights of undefined method calls so that genuine errors are more visible.
The least you can do to maximise method auto-completion:
1. Always provide type hints for method parameters where possible / appropriate - see PHP Type Hinting for more details e.g.
public function createUser (UserDetails $userDetails, array $roles)
2. Always give methods that have a return value PHPDoc comments (beginning /**) which at least define the #return type for the method (if not mixed) and the content type of any array parameters (if not mixed). e.g.
/**
* #param UserDetails $userDetails
* #param Role[] $roles
* #return User
*/
3. Use PHPDoc comments with #var to define the type of class member variables and local variables e.g.
class UserManager
{
/**
* #var EntityManager
*/
private $entityManager
...
public function doSomething()
{
...
/** #var User $user */
foreach($users as $user)
{
...
}
...
It is good practice generally to use PHP type hinting and to make appropriate use of PHPDoc.

Symfony2: How to have a form for an entity but with field not the same has properties

I have a Duo entity containing two persons. During the creation, the creator submits the email address partner and decides whether he is the captain or not of the new Duo. If he decides that he isn't (he choose the be the assistant) then, automatically, the second person is assigned captain. My Duo entity is as follows:
/**
* #ORM\Table()
* #ORM\Entity()
*/
class Duo{
/**
* #Assert\NotNull()
* #ORM\OneToOne(targetEntity="User")
* #ORM\JoinColumn(name="captain_id", referencedColumnName="id")
*/
private $captain;
/**
* #Assert\NotNull()
* #ORM\OneToOne(targetEntity="User")
* #ORM\JoinColumn(name="assistant_id", referencedColumnName="id")
*/
private $assistant;
I wonder how to organize my form so that there is only an email address that is submitted designating the partner. When I call $form->isValid(), I want my Duo entity to be valid. I do not want to use a form without entity because I do not want to have to assign data manually and handle errors outside of the form. Also, I would like to verify if one of the two users aren't involved in another Duo. If yes, how to pass the error message to the form in a clean way.
What should I do? Is there a way to do it using the Form Callbacks or Event or something like that?
Data transfers can do everything you want:
http://symfony.com/doc/current/cookbook/form/data_transformers.html
I suggest reading this very carefully, because it got very confusing the first time I did. There is a perfect example here that explains how to build issue id to Issue, basically same is your case.
As for the errors, I think your best option is to use Callback in combination with form constraints attribute:
http://knpuniversity.com/screencast/question-answer-day/custom-validation-property-path#creating-a-proper-custom-validation-constraint
You should probably read the whole article as there is not only "proper" way but "quick and dirty" as well.
Hope this helps.

BooleanGetMethodName warning in phpmd

I generate my entities using doctrine mapping in symfony2, and get this code:
/**
* Get active
*
* #return boolean
*/
public function getActive() {
return $this->active;
}
Using jenkins and PMD plugin, they throw BooleanGetMethodName warnings and suggest that because getActive function return boolean, it should be renamed to isActive or hasActive.
I have a lot of files that have this warning. Is it good to suppress the warnings? If yes, how? Or should I replace all functions name returning boolean value in symfony2 entity to follow jenkins and PMD rule?
By PMD you mean PHP Mess Detector?
If so, since you have a setup with Jenkins and PHP Mess Detector, I assume you actually care about code smells and readability.
With that in mind, my advice to you is: rename all of your boolean methods to follow the isSomething() or hasSomething() conventions.
Its important to notice though what code convention guide you follow.
That is very simple and quick to achieve, and will give you lots of benefits, such as:
Possible bugs. Bugs are not always wrongly written code. A lot of times, poor conditions or bad management of scope can generate pretty hard to find bugs.
Suboptimal code. Bad looking code can and most likely will be dificult to read. This is suboptimal code.
Overcomplicated expressions
Unused parameters, methods or properties

What purpose does #param annotation does in symfony2 class file

In the symfony2 and doctrine 2. I have this
/**
* Find a user by its username.
*
* #param string $username
* #return UserInterface or null if user does not exist
*/
function findUserByUsername($username);
Now i want to know that does it solve nay purpose or does it do anything in database with those #param and #return annotation or they just for documentation
#param is explained in the phpDocumentor docs. It has nothing to do with Symfony2.
The link is outdated.
Here is a link to a good address at this present moment.
https://www.phpdoc.org/docs/latest/references/phpdoc/tags/param.html
Below, the first lines of the explanation in any case...
The #param tag is used to document a single argument of a function or method.
With the #param tag it is possible to document the type and function of a single argument of a function or method. When provided it MUST contain a Type to indicate what is expected; the description on the other hand is OPTIONAL yet RECOMMENDED in case of complicated structures, such as associative arrays.

create a new entity based on the creation of another (postPersist) Doctrine2

I'm trying to create a new entity based on the creation of another. Example: I have a relationship
Sale <-- 1:M --> Payment
Now, when I persist a Sale, then you must create an initial Payment but i dont know exactly how do it.
i've try:
usage #ORM\HasLifecycleCallbacks(), #ORM\prePersist or #ORM\postPersist, but these methods does not get arguments and i can't persist the Entity Payment. I've even tried to relate Sale with Payment (in prePersist method $payment->setSale($this)) hoping EntityManager to persist Payment for me. info from here
I tried to create a listener (guided from here), but it just does not work, at no time the listener runs
Do it in my SaleController::createAction(), this way is obviously simple and it works, but this is nothing elegant and also goes against the good design of my application, this operation is part of the business logic and repeated in various parts
Out of the 3 solutions you listed 3 is still the least wrong in my opinion. It's simple, not overly complicated and easy to refactor later.
But if you're looking for a clean solution, I think what you need is a form handler or a similar service.
Take a look at FOSUserBundle one.
Basically you will create a PaymentManager class & after handling all the Sales form stuff, pass all the gathered info to PaymentManager and let it handle all the create/persist logic of Payment entity.
I'd suggest that a PaymentManager as suggested by #Inori is the best way to go, it is DRY and also a central point where entities are created. It allows you to marshal all the user input in the controller and then pass it onto the manager to build up the Sale object properly.
If you DO wish to go with the 1st option and use a lifecycle callback I assume you are getting an exception that says an unmanaged entity was found on another entity - or something to that effect. To get around this you can cascade persist on your mapping which means that you don't need to call persist for the Payment:
/**
* One-to-Many via Join Table (aka One-To-Many Unidirectional).
* #ORM\ManyToMany(targetEntity="Payment", cascade={"persist"})
* #ORM\JoinTable(
* inverseJoinColumns={
* #ORM\JoinColumn(unique=true, onDelete="CASCADE")
* }
* )
*/
You can read more about the One-To-One, Unidirectional if it confuses you.
Also you should read about cascade persist Transitive persistence / Cascade Operations.

Resources