I have a question about try catch bock exceptions. I want to know if I have a class called Image that makes images and in that class is a try catch statement and if there is an error I want my controller that makes the image to return the response, So in my controller I also have a catch statement what I want to know is what I have below correct and going to work when I have an error and if it aint going to work can you show me how my statements should be.
<?php
namespace App\Acme\Imaging;
use Image as Intervention;
class Image
{
public function __construct($input) {
}
public function save() {
try {
$image = Intervention::make(...);
$image->save(...);
} catch(NotReadableException $e) {
return response()->json(['error' => true, 'message' => $e->getMessage()], $e->getCode(), ['Content-Length' =>$e->getMessage()])
}
}
}
public function store(PostRequest $request)
{
try {
$image = new Image;
$image->width = 500;
$image->height = 500;
$image->save();
$post = new Post;
$post->fill($request->all());
$post->created_by = Auth::user()->id;
$post->image = $image;
if($post->save()) {
return response()->json($post, 200, ['Content-Lnegth' => strlen(json_encode($post))]);
}
} catch(Exception $e) {
return response()->json(array('error' => true, 'type' => 'exception', 'message' => $e->getMessage()), $e->getCode(), ['Content-Length' => strlen($e->getMessage())]);
}
}
Since you are not throwing the error, the controller will not catch it. In order to maintain the original error data, You could do something like this...
public function save() {
try {
$image = Intervention::make(...);
$image->save(...);
} catch(NotReadableException $e) {
throw new Exception('Error Saving file: ' . 'message: ' . e->getMessage() . ' code: ' . $e->getCode();
}
}
Then your calling function will enter the catch block and spit out the whole thing as part of it's $e->getMessage()
[...]
} catch( NotReadableException $e ) {
return json_encode( array(
'code' => $e
->response()
->getCode(),
'content-length' => $e
->response()
->getMessage()
) );
}
[...]
To encode something in json, you must use the json_encode() function. Assuming that the instanced NotReadableException is using the response() method to return an object holding the data, it may look something like the above.
response() indicates the current objects scope, you need to target the instanced Exception through the variable you created ($e), however, you have shown no code for that so I can only guess your hierarchy of it.
The below example on a non-extended Exception class looks like this:
try {
throw new Exception( "Example message." );
} catch ( Exception $e ) {
return json_encode( array (
'content-length' => $e
->getMessage()
) );
}
See it working here over at https://3v4l.org/O7WJF.
Related
I want customize my Laravel exception handler to return some JSON response, but I get empty result, with 500 http error.
I try it like this
public function register()
{
$this->renderable(function (Throwable $e) {
$status = $e->getCode();
$message = $e->getMessage();
$data = $e->getTrace();
return response()->json(['status' => $status, 'message' => $message, 'data' => $data], $status ?? 400);
});
}
Is this the correct way to do it?
I'd like to know what went wrong is it.
I want to use own Exception in try catch but I can't catch it.
Or maybe I catch it but is not what I want.
My php version is 7.4.30, laravel is 6.20.44.
Here is my code , I write a api to find a product , it's a get method.
api route
Route::get('/product/{id}', 'ProductCategoryController#find');
Execption
<?php
namespace App\Exceptions;
use Exception;
class ProductException extends Exception
{
public function render()
{
return response()->json([
'status' => 404,
'message' => 'product not found',
], 404);
}
}
Service
public static function find($id)
{
$product = ProductCategory::find($id);
if (!$product) {
throw new ProductException('ProductException', 400);
}
}
Controller
public function find($id)
{
return $this->ProductCategoryService->find($id);
try {
return $this->ProductCategoryService->find($id);
} catch (ProductException $e) {
return response()->json(['message' => $e->getMessage(), 'code' => $e->getCode()], 400);
}
}
I want to know my controller just use
return $this->ProductCategoryService->find($id);
I can get my onw exception response like this
When I commented off change to use try catch i will get
Why try catch catch exception is catch I throw parameters not catch
public function render()
{
return response()->json([
'status' => 404,
'message' => 'product not found',
], 404);
}
I want to know how it happened? and how to fix it
Thanks
I know that for experienced Laravel developers this question my sound silly, but I followed this article for implementing Facebook SDK.
I followed everything from adding new token column in database to implementing controller.
This is my GraphController.php file:
class GraphController extends Controller
{
private $api;
public function __construct(Facebook $fb)
{
$this->middleware(function ($request, $next) use ($fb) {
$fb->setDefaultAccessToken(Auth::user()->token);
$this->api = $fb;
return $next($request);
});
}
public function getPageAccessToken($page_id){
try {
// Get the \Facebook\GraphNodes\GraphUser object for the current user.
// If you provided a 'default_access_token', the '{access-token}' is optional.
$response = $this->api->get('/me/accounts', Auth::user()->token);
} catch(FacebookResponseException $e) {
// When Graph returns an error
echo 'Graph returned an error: ' . $e->getMessage();
exit;
} catch(FacebookSDKException $e) {
// When validation fails or other local issues
echo 'Facebook SDK returned an error: ' . $e->getMessage();
exit;
}
try {
$pages = $response->getGraphEdge()->asArray();
foreach ($pages as $key) {
if ($key['id'] == $page_id) {
return $key['access_token'];
}
}
} catch (FacebookSDKException $e) {
dd($e); // handle exception
}
}
public function publishToPage(Request $request, $title){
$page_id = 'XXXXXXXXXXXXX';
try {
$post = $this->api->post('/' . $page_id . '/feed', array('message' => $title), $this->getPageAccessToken($page_id));
$post = $post->getGraphNode()->asArray();
} catch (FacebookSDKException $e) {
dd($e); // handle exception
}
}
}
This is my routes/web.php :
Route::group(['middleware' => [
'auth'
]], function(){
Route::post('/page', 'GraphController#publishToPage');
});
FacebookServiceProvider:
class FacebookServiceProvider extends ServiceProvider
{
/**
* Register services.
*
* #return void
*/
public function register()
{
$this->app->singleton(Facebook::class, function ($app) {
$config = config('services.facebook');
return new Facebook([
'app_id' => $config['client_id'],
'app_secret' => $config['client_secret'],
'default_graph_version' => 'v2.6',
]);
});
}
}
Now, I would need to use publishToPage inside of my PostController.php file:
public function store(Requests\PostRequest $request)
{
$data = $this->handleRequest($request);
$newPost = $request->user()->posts()->create($data);
$newPost->createTags($data["post_tags"]);
/*
// My other notifications that are working:
// OneSignal
OneSignal::sendNotificationToAll(
"New warning ".$newPost->title
);
// MailChimp
$this->notify($request, $newPost);
// Twitter
$newPost->notify(new ArticlePublished());
*/
// I WOULD NEED SOMETHING IN THIS WAY ALSO FOR FACEBOOK BUT THIS OBVIOUSLY DOESN'T WORK
GraphController::publishToPage($request, $newPost->title);
}
Can you please suggest good way how to do it from here?
I need to apologize again if this seems to you like basics of Laravel that I should know, but I really struggling to wrap my head around this and your suggestions would really help me to understand it better.
Integrating Twitter, MailChimp, OneSignal notifications was really easy but Facebook restricted policies makes it quite confusing for me.
Thank you guys. I really appreciate it!
Sadly, Facebook still didn't get me permission for auto posting so I cannot try, if it realy works.
I think I found a solution to this particular problem though. Credit goes to Sti3bas from Laracast.
namespace App\Services;
class FacebookPoster
{
protected $api;
public function __construct(Facebook $fb)
{
$fb->setDefaultAccessToken(Auth::user()->token);
$this->api = $fb;
}
protected function getPageAccessToken($page_id){
try {
// Get the \Facebook\GraphNodes\GraphUser object for the current user.
// If you provided a 'default_access_token', the '{access-token}' is optional.
$response = $this->api->get('/me/accounts', Auth::user()->token);
} catch(FacebookResponseException $e) {
// When Graph returns an error
echo 'Graph returned an error: ' . $e->getMessage();
exit;
} catch(FacebookSDKException $e) {
// When validation fails or other local issues
echo 'Facebook SDK returned an error: ' . $e->getMessage();
exit;
}
try {
$pages = $response->getGraphEdge()->asArray();
foreach ($pages as $key) {
if ($key['id'] == $page_id) {
return $key['access_token'];
}
}
} catch (FacebookSDKException $e) {
dd($e); // handle exception
}
}
public function publishToPage($page, $title){
try {
$post = $this->api->post('/' . $page . '/feed', array('message' => $title), $this->getPageAccessToken($page));
$post = $post->getGraphNode()->asArray();
} catch (FacebookSDKException $e) {
dd($e); // handle exception
}
}
}
Then refact controllers:
use App\Services\FacebookPoster;
//...
class GraphController extends Controller
{
public function publishToPage(Request $request, FacebookPoster $facebookPoster)
{
$page_id = 'XXXXXXXXXXXXX';
$title = 'XXXXXXXXXXXXX';
$facebookPoster->publishToPage($page_id, $title);
}
}
use App\Services\FacebookPoster;
//...
public function store(PostRequest $request, FacebookPoster $facebookPoster)
{
$data = $this->handleRequest($request);
$newPost = $request->user()->posts()->create($data);
$newPost->createTags($data["post_tags"]);
//...
$facebookPoster->publishToPage($page, $newPost->title);
}
I have a function
public function getCandidates($candidateEmail)
{
try {
$moduleIns = ZCRMRestClient::getInstance()->getModuleInstance('Candidats');
$response = $moduleIns->searchRecordsByEmail($candidateEmail, 1, 1);
$candidates = $response->getResponseJSON();
return $candidates;
} catch (ZCRMException $e) {
echo $e->getMessage();
echo $e->getExceptionCode();
echo $e->getCode();
}
}
And I use this function like that :
$obj = new ZohoV2();
$response = $obj->getCandidates($request->email);
$candidate = $response['data'][0];
return response()->json([ 'status' => 'success', 'candidate' => $candidate ], 200);
Theses functions allows me to retrieve a user from a database of a CRM.
But when the user does not exist, he sends me a 500 error.
{message: "No Content", exception: "zcrmsdk\crm\exception\ZCRMException",…}
exception: "zcrmsdk\crm\exception\ZCRMException"
file: "/home/vagrant/CloudStation/knok/myath/myath-app/vendor/zohocrm/php-sdk/src/crm/api/response/BulkAPIResponse.php"
line: 61
message: "No Content"
trace: [{,…}, {,…}, {,…}, {,…}, {,…}, {,…},…]
How to intercept this error so that I can process it as I want and send an error message ?
Thank you
Remove the try/catch from your first code block
public function getCandidates($candidateEmail)
{
$moduleIns = ZCRMRestClient::getInstance()->getModuleInstance('Candidats');
$response = $moduleIns->searchRecordsByEmail($candidateEmail, 1, 1);
$candidates = $response->getResponseJSON();
return $candidates;
}
And move it to the second code block (I assume it's the controller)
$obj = new ZohoV2();
try {
$response = $obj->getCandidates($request->email);
} catch (ZCRMException $e) {
return response()->json(['status' => 'failed', 'error' => $e->getMessage()], 404);
}
$candidate = $response['data'][0];
return response()->json([ 'status' => 'success', 'candidate' => $candidate ], 200);
Here is the code:
try {
$result = Model_User::update_user($_POST);
// message: save success
Message::add('success', __('Values saved.'));
// redirect and exit
$this->request->redirect('user/profile');
return;
} catch (Exception $e) {
// Get errors for display in view
// Note how the first param is the path to the message file (e.g. /messages/register.php)
Message::add('error', __('Error: Values could not be saved.'));
$errors = $e->errors('register');
$errors = array_merge($errors, (isset($errors['_external']) ? $errors['_external'] : array()));
$view->set('errors', $errors);
// Pass on the old form values
$user->password = '';
$view->set('data', $user);
}
Here is the code of update_user method in Model_User:
public function update_user($fields)
{
$validation = Validation::factory($fields)
->rules('password', $this->_rules['password'])
->rules('password_confirm', $this->_rules['password_confirm'])
->filters('password', $this->_filters['password']);
$this->validate($fields);
$users = CASSANDRA::selectColumnFamily('Users');
if ($users->get_cout($username))
{
return $users->insert($uuid, array(
'username' => $fields['username'],
'password' => $fields['password'],
'email' => $fields['email'],
'modify' => date('YmdHis', time()),
));
}
else
{
return $validation;
}
}
I am now getting this error:
ErrorException [ Fatal Error ]: Call to undefined method ErrorException::errors()
Stuck on this line:
117 $errors = $e->errors('register');
Thanks in advance for any help!
You need to catch a Validation_Exception for handling validation errors.
Only this kind of exception has an errors() method. Your code is throwing some other kind of exception, for which you need to do the error handling yourself.
So, change
} catch (Exception $e) {
to
} catch (Validation_Exception $e) {
$errors = $e->errors('register');
...
} catch (Exception $e) {
// Do your error handling by hand
}