嵌套Laravel Try catch不抛出内部异常,仅外部异常

时间:2019-05-14 09:29:12

标签: php laravel laravel-5 eloquent try-catch

我对Try Catch块有点模糊,直到现在我只是在其中放了一些代码并试图捕获错误。我现在在Laravel中使用它们,但是在嵌套语句时似乎无法正确触发异常,我只是想知道是否有人可以解释原因或将我指向正确的方向!

我有3种模型:案例成员文档

这里是我想要实现的目标

  

尝试存储案例,成员和任何上传的文档(包括将文档移动到存储文件夹)。如果任何失败,请还原所有内容。

我正在将案例和成员存储运行在DB::transaction函数内部,该函数运行良好,但是我想在外部将文档移动/存储在文档模型中。

保存表单时,首先触发大小写store函数。

到目前为止,这是我的模型/控制器

案例控制器

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
         }
    }

文档模型

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;
        }
    }

我通过在保存文档时强制调用storeNewDocument而不是$nwName来伪造Document $newName函数中的错误。

目前发生的是

  

案例和成员不会创建(我相信这是正确的,因为在某处引发了错误,因此交易无法完成?)

     

该文件在Document storeNewDocument函数中成功移动,并登陆到storage/cases文件夹中,这是正确的。

     

然后,文档无法保存,但是文档模型上的catch中的dd($e)没有被击中?

     

这时,文档,案例和成员DB记录尚未保存,但是在文档模型中根本没有触发该捕获,因此我找不到该文件并将其删除?

我真的不确定嵌套的try / catch语句如何工作。有人可以让我知道为什么我的Document模型上的陷阱没有触发,或者我是否试图以完全愚蠢的方式实现我的目标吗?!

任何澄清将不胜感激!

注意-$this->checkDirectory()函数只是检查该函数是否存在,如果不存在则创建它,该函数没有问题,只是没有发现问题所在将其添加到问题中。

更新-该错误似乎是每当文档模型函数中引发错误时,它总是首先遇到Case store函数中的问题。例如,如果我放弃了捕获中的dd($e)函数,则在我的日志文件中,日志消息不是Document Move Error,而是始终为Cases Create Error,对我来说,文档storeNewDocument的渔获量从未被击中?

1 个答案:

答案 0 :(得分:0)

我认为您只需要重新抛出异常即可。

        } catch (Exception $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);
            //throw $e
            throw $e;
        }

您正在从另一个catch / catch块内的catch块返回false。