public function update($memberId, Request $request)
 {
     // basic validation
     $validate = Validator::make($request->all(), ['displayName' => 'required']);
     if ($validate->fails()) {
         $message = $validate->messages()->first();
         $e = new InvalidArgumentException();
         $e->setMessage($message);
         throw $e;
     }
     // member validation
     /** @var MemberEntityInterface $member */
     $member = $this->handler->findMember($memberId);
     if ($member === null) {
         throw new MemberNotFoundException();
     }
     $displayName = $request->get('displayName');
     $introduction = $request->get('introduction');
     // displayName validation
     if ($member->getDisplayName() !== trim($displayName)) {
         $this->handler->validateDisplayName($displayName);
     }
     // apply updated
     $member->displayName = $displayName;
     if ($introduction !== null) {
         $member->introduction = $introduction;
     }
     XeDB::beginTransaction();
     try {
         // resolve profile file
         if ($profileFile = $request->file('profileImgFile')) {
             /** @var MemberImageHandler $imageHandler */
             $imageHandler = app('xe.member.image');
             $member->profileImageId = $imageHandler->updateMemberProfileImage($member, $profileFile);
         }
         $this->handler->update($member);
     } catch (\Exception $e) {
         XeDB::rollback();
         throw $e;
     }
     XeDB::commit();
     return redirect()->route('member.profile', [$member->getId()])->with('alert', ['type' => 'success', 'message' => '변경되었습니다.']);
 }