【问题标题】:Nested Laravel Try catch not throwing inner Exception, only outer嵌套 Laravel 尝试捕获不抛出内部异常,仅抛出外部异常
【发布时间】:2019-05-14 09:29:12
【问题描述】:

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

我有 3 个模型,案例成员文档

这就是我想要实现的目标

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

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

我在 Document storeNewDocument 函数中伪造了一个错误,方法是在保存文档时尝试调用 $nwName 而不是 $newName 来强制出错。

目前发生的是

案例和成员未创建(我相信这是正确的,因为在某处抛出错误,因此交易未完成?)

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

然后文档保存失败,但是文档模型的catch里面的dd($e)没有命中?

此时文档、案例和成员数据库记录还没有保存,但是文档模型中的catch根本没有触发,所以我找不到文件并删除它?

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

任何形式的澄清将不胜感激!

注意 - $this->checkDirectory() 函数只是检查函数是否存在,如果不存在则创建它,这个函数没有问题,只是没有看到添加的意义它进入问题。

update - 错误似乎是每当在文档模型函数中抛出错误时,它总是首先在 Case store 函数中遇到问题。例如,如果我去掉了catch中的dd($e)函数,在我的日志文件中,日志消息不是Document Move Error,它总是Cases Create Error,对我来说,文件storeNewDocumentcatch是从未被击中?

【问题讨论】:

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


    【解决方案1】:

    我认为你只需要重新抛出你的异常。

            } 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 块返回 false,它位于另一个 try/catch 块中。

    【讨论】:

    • 它根本没有命中那个catch,我认为每当storeNewDocument try catch中抛出错误时,它永远不会命中storeNewDocument catch,它会自动命中store的情况赶上。
    猜你喜欢
    • 2018-08-31
    • 1970-01-01
    • 2016-02-17
    • 2011-12-07
    • 2013-10-04
    • 2013-06-24
    • 2021-01-15
    • 2012-07-27
    • 1970-01-01
    相关资源
    最近更新 更多