I'm a little bit fuzzy with Try Catch blocks, up until now i've just put some code inside them and tried to catch the error. I'm now using them in Laravel but I cant seem to get the exception to fire correctly when nesting statements, and i'm just wondering if someone can explain why or point me in the right direction!
I have 3 models, cases, members and documents.
Heres what I want to achieve
Try to store cases, members and any documents upload (including moving documents to storage folder). If any fail, revert everything.
I am running the cases and members store inside a DB::transaction function which is working great, but I then want to run my document move/store in the document model externally.
When I save my form, the case store function is whats fired first.
Here are my models/controllers so far
Case Controller
public function store(AddCaseRequest $request)
{
//Try to create a new case
try{
//New Case
$case = new Cases;
//New Member
$member = new Members;
DB::transaction(function() use ($case, $member) {
//Save Case
$case->fill(request()->all())->save();
//Save Member
$member->fill(request()->all())->save();
//Documents
if(request()->has('document')){
//Loop the documents and store
foreach(request()->document as $doc){
$document = with(new Documents)->storeNewDocument($doc, $case->id, 'case', 'cases');
}
}
}, 3);
//Redirect back to view page
return redirect()->route('cases.view', [$case->id]);
}
//Catch the error
catch(\Exception $e){
//Log the error
Log::debug('Cases Create Error', (Array) $e->getMessage());
//Redirect back
return redirect()->back() //Redirect back
->withErrors(['Whoops! Something went wrong, please try again.']) //Send an error message
->withInput(request()->all()); //Send the inputs back
}
}
Document Model
public function storeNewDocument($file, $id, $type, $directory)
{
//Check the directory exists
if($this->checkDirectory($directory)){
//Get the file extention
$extension = $file->getClientOriginalExtension();
//Generate a new filename
$newName = md5(uniqid(rand(), true)) . "." . $extension;
//Move the file
try {
//Try to move the file
Storage::disk('local')->putFileAs($directory, $file, $newName);
//Create the new record
$document = new $this;
$document->type = $type;
$document->foreign_id = $id;
$document->nice_name = $file->getClientOriginalName();
$document->name = $nwName;
$document->save();
} catch (Exception $e){
dd($e);
//Log the error
Log::debug('Document Move Error', (Array) $e->getMessage());
//Try to delete the file incase the document save failed
Storage::delete($directory . '/' . $newName);
//Return false
return false;
}
//All moved, return the new name
//return $newName;
}
}
I have faked an error in the Document storeNewDocument function, by trying to call $nwName instead of $newName when saving the document to force an error.
What currently happens is
Case and member do not create (which is correct I believe because there is an error being thrown somewhere so the transaction doesn't complete?)
The file moves successfully in the Document
storeNewDocumentfunction, and lands in thestorage/casesfolder, which is correct.The document then fails to save, but the
dd($e)inside the catch on the document model is not hit?At this point the document, case and member DB records have not saved, but the catch doesn't fire at all in the document model, so I cannot find the file and delete it?
I'm really not sure on how nested try/catch statements work. Can someone please let me know why the catch on my Document Model is not firing or if i'm trying to achieve my goal in a completely stupid way?!
Any sort of clarification would be massively appreciated!
Note - The $this->checkDirectory() function simply just checks if the function exists and create it if it doesn't, there is no issue with this function, just didn't see the point in adding it in to the question.
update - The error seems to be whenever an error is thrown inside the document model functions, it always hits the catch in the Case store function first. For example, if I got rid of the dd($e) function in the catch, in my log file, the log message is not Document Move Error, it is always Cases Create Error, which to me says that the document storeNewDocument catch is never being hit?