Reputation: 1331
I just ran into a problem where i can't seem to find a proper way of handling. I know this is a stupid example, but its the fastest i could think of.
UserController
trait SaveUser;
public function example(Request $request){
$user = $this->saveUser($request->name);
return $user;
}
Trait SaveUser;
public function saveUser($name){
$is_valid = $this->validateUser;
if(!is_valid) return response()->json(['data' => null,'message' => "please enter a name for the user",],500);
try{
$user = new User();
$user->name = $name;
$user->save()
return $user;
}catch(\Exception $e){
return response()->json(['data' => null,'message' => "error saving the user.",],500);
}
}
private function validateUser($name){
if($name == null)
return false;
return true;
}
Lets say i am saving a user, requesting the name from the api request. I send it to a trait because its going to be used in many places, if the user name is not valid, it returns a json response saying it needs to be set, else if an error occurs while saving the user, return a code 500
response. Now this is a simple example, on my case, i have the validate
method validate many other things and each have a unique message for a response, same for attributes of the user, etc..
So pretty much my problem is, that when the try catch
catches an execption or something is not valid, it returns return response()->json(['data' => null,'message' => "error saving the user.",],500);
to the $user
in the UserController variable. What i would like it to do is, end my code in the exception or in the return response()->
and return the response. Is there anyway i can just end the code anywhere that i have return response()->...
?
I am using this in an API, this is just a quick example. Any help would be appreciated. Thanks
Upvotes: 0
Views: 1430
Reputation: 33148
I really don't mean any offense by this but this seems to be a case where you are trying to cover up bad practices with more bad practices.
Your first problem is trying to return responses from methods which aren't in your routes file. You can do this and it should work just fine because in your example, your just returning that response anyway which is being stored in the $user
variable.
The cover-up for this which you are asking for is how to now handle functions returning either Response
objects or User
objects. So you would essentially have to use instanceof
to determine if this object is a Response
or User
. if it's a response, return it, otherwise, keep doing more work.
This isn't terrible because you only have to add a few more conditions but I don't think it's a road you want to start going down because it has potential to snowball from there and create very un-maintainable code.
I'd suggest you start thinking about it this way. Why is the saveUser
function worried about validating the user when we already have a validateUser
function. Let the function which is being called by the routes do all the "controlling" and let your other functions do just what they were intended to do and nothing else. They should basically just act as helper functions to separate out different parts of your logic.
There are many ways to handle this but I'd suggest something like the following.
public function example(Request $request)
{
// Do all the "controlling" in this function, other functions should just be handling all the business logic.
if (! $this->validateUser($request->name)) {
return response()->json(['data' => null,'message' => "please enter a name for the user",],500);
}
try {
$user = $this->saveUser($request->name);
} catch (Exception $e) {
return response()->json(['data' => null,'message' => "error saving the user.",],500);
}
// Here we know this will always be a User object.
return $user;
}
public function saveUser($name)
{
$user = new User();
$user->name = $name;
$user->save();
return $user;
}
private function validateUser($name)
{
if($name == null) {
return false;
}
return true;
}
Upvotes: 2
Reputation: 46
I am pretty sure the only way to return response to the user is by returning it from function/method called by Router.
So the "cleanest" way would be to have another variable with error response either passed by reference or from returned array and if there's error return it instead of user object
UserController
public function example(Request $request){
$err = NULL;
$user = $this->saveUser($request->name, $err);
return ($err != NULL) ? $err : $user;
}
SaveUser
public function saveUser($name, &$err){
$is_valid = $this->validateUser;
if(!is_valid)
$err = response()->json(['data' => null,'message' => "please enter a name for the user",],500);
try{
$user = new User();
$user->name = $name;
$user->save()
return $user;
}catch(\Exception $e){
$err = response()->json(['data' => null,'message' => "error saving the user.",],500);
}
}
private function validateUser($name){
if($name == null)
return false;
return true;
}
Upvotes: 1