Why I failed to catch ModelNotFoundException ths error in controller block? - laravel

In laravel 9 I have ProductCardReport component which is on blade form and data are retrieved
from ReportProduct class. I got data with firstOrFail in this class and I failed to catch this
error in controller block. I have in ProductController controller :
public function showReport(string $productId)
{
try {
return view('admin/products/report', [
'productId' => $productId,
]);
} catch (ModelNotFoundException $e) { // I EXPECTED THIS BLOCK WOULD WORK
\Log::info('-1ModelNotFoundException:');
return redirect(route('admin.products.edit', $this->productId))
->with('message', 'Product "' . $this->productId . '" not found.')
->with('message_type', 'error');
} catch (Exception $e) {
\Log::info('-1 ProductCardReport -2 showReport $e->getMessage() ::' . print_r($e->getMessage(), true));
return back()->withErrors(['message' => $e->getMessage()]);
}
}
In view 'admin/products/report' I set component :
<x-app-layout>
<x-product-card-report product-id="{{ $productId }}" />
</x-app-layout>
and in component app/View/Components/ProductCardReport.php :
public function render()
{
$reportProduct = new ReportProduct();
$itemRetrieved = $reportProduct->retrieveItem( id : $this->productId );
...
}
And in app/Library/ReportProduct.php I get data with invalid ID :
class ReportProduct implements ReportRetrieveItemInterface, ReportDownloadItemInterface
{
public function __construct()
{
$uploadedFileManagement= app(UploadedFileManagementInterface::class);
$this->uploadedFileManagement = $uploadedFileManagement;
}
public function retrieveItem(string $id, array $getRelatedData = []) : bool
{
$this->product = Product
::getById($id .'ERROR') // ModelNotFoundException is raised here.
->firstOrFail();
But I got uncaught error :
Illuminate\Database\Eloquent\ModelNotFoundException
No query results for model [App\Models\Product].
and try block in ProductController did not work.
How it can be fixed ?
Thanks!

Related

delete image from desk and table in morph relation in laravel

i have many to many morph relation in laravel and i want to update model that have images in attachmnets table
my Specialization model
public function attachments()
{
return $this->morphToMany(Attachment::class, 'attachmentable');
}
my Attachment model
public function specializations()
{
return $this->morphedByMany(Specialization::class, 'attachmentable');
}
my attachmentables model
protected $fillable = [
'attachment_id',
'attachmentable_id',
'attachmentable_type',
'key',
];
my controller update function
public function updatee($request, $id){
if($request->hasfile('image')){
$image = $this->uploadImages($request->image , 'specialiations/images');
$specialization = Specialization::where('id',$id)->with('attachments')->first();
if($specialization != null){
$this->attachmentRepository->destroy($specialization->attachments[0]->id, $request);
try {
unlink(public_path().$request->file);
} catch (\Throwable $th) {
//throw $th;
}
}
$spec = $this->update($request->all(),$id,$request);
$specImage = $this->attachmentRepository->create(['file'=>$image]);
$att = $this->attachmentAbleRepository->create([
'attachment_id' => $specImage->id,
'attachmentable_id' => $spec->id,
'attachmentable_type' => 'App\Models\Specialization',
'key' => 'specialization',
]);
}
return $spec;
}
i have an error "Undefined array key 0" or "attempt [id]"

How to catch server's error in inertiajs request?

In laravel 8 / inertiajs 0.10 / vue 3 I want to catch some error which happens on server, like :
this.form.post(this.route('ads.store'), {
preserveScroll: true,
onSuccess: (p) => { // On succdess I see this message
console.log('onSuccess p::')
console.log(p)
Swal.fire(
'New Ad',
'Your post has successfully been published!',
'success'
)
this.form.description = null
},
onError: (p) => { // That is not triggered!
console.log('onError p::')
console.log(p)
}
})
In control :
public function store( AdFormRequest $request) {
$data = $request->all();
$data['status']= 'A';
$ad = Ad::create($data);
return $request->wantsJson()
? new JsonResponse($ad, 200)
: back()->with('status', 'Error saving add');
}
So if one of required fields is empty I got laravel error popup window...
How to catch it and to show it in Swal.fire ?
MODIFIED # 1:
Searching in net I found onError property, but making :
this.deleteForm.delete(this.route('ads.destroy', this.nextAd), {
preserveScroll: true,
onError: (p) => { // THIS PART IS NOT CALLED ON ERROR
console.log('onError p::')
console.log(p)
Swal.fire(
'Delete Ad',
'Error deleting ad!',
'error'
)
},
onSuccess:()=>{
Swal.fire( // THIS PART IS CALLED ON SUCCESS
'Delete Ad',
'Your post has successfully been Delete!',
'success'
)
}
})
and in control :
public function destroy(Request $request, Ad $ad) {
try {
DB::beginTransaction();
$ad->deleTTTte();
DB::commit();
} catch (QueryException $e) {
DB::rollBack(); // I SEE THIS MESSAGE IN LOG FILE ON ERROR
\Log::info( '-1 AdController store $e->getMessage() ::' . print_r( $e->getMessage(), true ) );
return $request->wantsJson()
? new JsonResponse($ad, 500 /*HTTP_RESPONSE_INTERNAL_SERVER_ERROR*/ )
: back()->with('status', 'Error adding ad : ' . $e->getMessage());
return;
}
return $request->wantsJson()
? new JsonResponse($ad, HTTP_RESPONSE_OK)
: back()->with('status', 'Ad saved succesully');
}
Which way is correct?
Thanks!
The onError() callback is only called when there is a specific flag in the session called errors. So, in you server's catch block you need to flash the errors in the user's session and redirect to your calling page:
try {
// errors throw here
} catch {
return back()->with('errors', 'Error adding ad');
}

Laravel Form Request unique field validation on update

I have to make Form Request and have a unique rule on the title. How to ignore unique validation for updating id?
These are my rules when I try to get an id passed from the controller.
public function rules()
{
$id = $this->request->get('id') ? ',.' $this->request->get('id') : '';
$rules = [
'title' => 'required|min:3|unique:parent_categories',
];
if ($this->getMethod() == 'PUT' || $this->getMethod() == 'PATCH') {
$rules += ['title' => 'required|min:3|unique:parent_categories,title' . $id];
}
return $rules;
}
This is my controller where I am trying to update content with id.
public function update(ParentCategoryRequest $request, $id)
{
DB::beginTransaction();
try {
$parentCategory = ParentCategory::update($id, $request->all());
DB::commit();
return $this->success('Parent category updated successfully', new ParentCategoryResource($parentCategory), 201);
} catch (Exception $e) {
DB::rollBack();
return $this->error($e->getMessage(), $e->getCode());
}
}
I am getting...
undefined variable $id on ParentCategoryRequest

Undefined property: GuzzleHttp\Exception\ConnectException::$status

I keep getting this error when trying to get the status of the request.
This is my code
ExpenseRepository.php
<?php
namespace Expensetrim\Api\v1\Repositories;
use Auth;
use GuzzleHttp\Client;
use GuzzleHttp\Exception\RequestException;
use Expensetrim\Models\Company;
use Illuminate\Support\Facades\DB;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
class ExpenseRepository
{
private $api_url;
const API_GET = 'GET';
const API_POST = 'POST';
const API_PUT = 'PUT';
function __construct()
{
$this->api_url = "http://xxx-xxx-xxx/api/v1/";
}
public function api_call($method, $uri, $request = NULL)
{
try {
$url=$this->api_url.$uri;
$client = new Client(['base_uri' => $this->api_url]);
$response = ($request) ? $client->request($method, $uri, $request) : $client->request($method, $uri);
}
catch (RequestException $e) {
return $e;
}
return $this->formatResponseBody($response);
}
public static function formatResponseBody($response)
{
$body = $response->getBody(true)->getContents();
return json_decode($body);
}
public function addExpenseType($data)
{
$uri = 'expense/types/add';
$response = $this->api_call(self::API_POST, $uri, ['form_params' => $data]);
return $response;
}
Also CompanyRepository.php
public function addExpenseType($company_id, $data)
{
$data['company_id'] = $company_id;
$expense = new ExpenseRepository;
$done = $expense->addExpenseType($data);
if($done->status == 'success') {
return true;
}
return true;
}
I need to check if the status is a success or not but keep getting this error: Undefined property: GuzzleHttp\Exception\ConnectException::$status.
Please what am i doing wrong?
There is an exception thrown at this line:
catch (RequestException $e) {
return $e;
}
and you are returning the exception. The return value of the method addExpenseType is actually an exception thrown by Guzzle.
throw the exception to see the error.
change your code to
catch (RequestException $e) {
throw $e;
}
Change your formatResponseBody function to add $response->getBody()->rewind();
public static function formatResponseBody($response)
{
$response->getBody()->rewind();
$body = $response->getBody(true)->getContents();
return json_decode($body);
}
In the old version of guzzle, it read the full body without resetting the pointer after. Using rewind() will reset the pointer. If this is the source of your issue rewind() will resolve this. It has aleady been resolved in newer versions.

Laravel call to a member function on null when using assertsee

So all my other tests are working except this one when I test the view if it has this string or not. Problem is I'm getting an error message that the method being called is on null but is working when I access the page.
Error message:
Symfony\Component\Debug\Exception\FatalThrowableError: Call to a member function getCode() on null
/home/vagrant/Code/team-stores/app/Http/Controllers/StoreManager/OrderTrackingController.php:20
/home/vagrant/Code/team-stores/vendor/laravel/framework/src/Illuminate/Routing/Controller.php:55
/home/vagrant/Code/team-stores/vendor/laravel/framework/src/Illuminate/Routing/ControllerDispatcher.php:44
/home/vagrant/Code/team-stores/vendor/laravel/framework/src/Illuminate/Routing/Route.php:203
/home/vagrant/Code/team-stores/vendor/laravel/framework/src/Illuminate/Routing/Route.php:160
/home/vagrant/Code/team-stores/vendor/laravel/framework/src/Illuminate/Routing/Router.php:574
/home/vagrant/Code/team-stores/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php:30
/home/vagrant/Code/team-stores/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php:102
/home/vagrant/Code/team-stores/vendor/laravel/framework/src/Illuminate/Routing/Router.php:576
/home/vagrant/Code/team-stores/vendor/laravel/framework/src/Illuminate/Routing/Router.php:535
/home/vagrant/Code/team-stores/vendor/laravel/framework/src/Illuminate/Routing/Router.php:513
/home/vagrant/Code/team-stores/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php:174
/home/vagrant/Code/team-stores/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php:30
/home/vagrant/Code/team-stores/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php:102
/home/vagrant/Code/team-stores/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php:149
/home/vagrant/Code/team-stores/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php:116
/home/vagrant/Code/team-stores/vendor/laravel/framework/src/Illuminate/Foundation/Testing/Concerns/MakesHttpRequests.php:234
/home/vagrant/Code/team-stores/tests/Feature/OrderTrackingTest.php:152
Test:
public function an_admin_can_view_all_orders_with_their_status()
{
$this->withoutMiddleWare();
StoreSession::setMyStore($this->store->code);
$orders = factory(CompletedOrder::class, 30)->create(['store_id' => $this->store->id]);
foreach ($orders as $order) {
factory(CompletedOrderItem::class, 5)->create(['completed_order_id' => $order->id]);
}
$response = $this->call("GET", route('list_completed_orders'));
foreach ($orders as $order) {
$response->assertSee($order->invoice()->getCode());
}
}
Controller:
public function index()
{
$store = StoreSession::getMyStore();
$completedOrders = CompletedOrder::where('store_id', $store->getId() )->get();
foreach ($completedOrders as $order) {
Log::info($order->invoice()->getCode());
}
return view('store-manager.order-tracking.index', compact('store', 'completedOrders'));
}
Thanks in advance.

Resources