Deleting an email account and re-creating it is totally broken

Issue #528 resolved
Greg created an issue

Using latest 2.0.20 poste, I created an email account for a virtual domain (also set it to be a system administrator). I then decided I didn't want this account to be able to administer the poste instance, but since there is no way to disable that setting once it is set (clicking "Edit" does not show the checkbox), I had to delete the account and re-create it.

However, attempting to re-create the account brought me to a large "500 Internal Server Error" page, which I've copied here:

Oops! An Error Occurred
The server returned a "500 Internal Server Error".

Something is broken. Please let us know what you were doing when this error occurred. We will fix it as soon as possible. Sorry for any inconvenience caused.
Failed to create symbolic link from "/data/domains/mywebsite.com/contact/sieve/Default.sieve" to "/data/domains/mywebsite.com/contact/.dovecot.sieve".
Symfony\Component\Filesystem\Exception\ IOException
in vendor/symfony/symfony/src/Symfony/Component/Filesystem/Filesystem.php (line 394)

            if (self::$lastError) {
                if ('\\' === \DIRECTORY_SEPARATOR && false !== strpos(self::$lastError, 'error code(1314)')) {
                    throw new IOException(sprintf('Unable to create %s link due to error code 1314: \'A required privilege is not held by the client\'. Do you have the required Administrator-rights?', $linkType), 0, null, $target);
                }
            }
            throw new IOException(sprintf('Failed to create %s link from "%s" to "%s".', $linkType, $origin, $target), 0, null, $target);
        }
        /**
         * Resolves links in paths.
         *

Filesystem->linkException('/data/domains/mywebsite.com/contact/sieve/Default.sieve', '/data/domains/mywebsite.com/contact/.dovecot.sieve', 'symbolic') in vendor/symfony/symfony/src/Symfony/Component/Filesystem/Filesystem.php (line 345)

                }
                $this->remove($targetDir);
            }
            if (!self::box('symlink', $originDir, $targetDir)) {
                $this->linkException($originDir, $targetDir, 'symbolic');
            }
        }
        /**
         * Creates a hard link, or several hard links to a file.

Filesystem->symlink('/data/domains/mywebsite.com/contact/sieve/Default.sieve', '/data/domains/mywebsite.com/contact/.dovecot.sieve') in src/AppBundle/Handler/Sieve.php (line 23)

        public function setSieve(Box $box, SieveScript $script): void
        {
            if (!is_file($box->getHome() . '/.dovecot.sieve')) {
                $this->fs->safeMkdir($box->getHome() . '/sieve');
                $this->fs->safeDumpFile($box->getHome() . '/sieve/Default.sieve', '');
                $this->fs->symlink($box->getHome() . '/sieve/Default.sieve', $box->getHome() . '/.dovecot.sieve');
            }
            $this->fs->safeDumpFile($box->getHome() . '/.dovecot.sieve', $script->script);
        }

Sieve->setSieve(object(Box), object(SieveScript)) in src/AppBundle/EventSubscriber/BoxEventSubscriber.php (line 72)

                    $filter->recipients = $entity->getRedirectTo();
                } else {
                    $filter = new SpamFolderFilter();
                }
                $this->sieve->setSieve($entity, new SieveScript($filter->export()));
            }
        }
        public function postUpdate(LifecycleEventArgs $args): void
        {

BoxEventSubscriber->postPersist(object(LifecycleEventArgs)) in vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/ContainerAwareEventManager.php (line 61)

                foreach ($this->listeners[$eventName] as $hash => $listener) {
                    if (!$initialized && \is_string($listener)) {
                        $this->listeners[$eventName][$hash] = $listener = $this->container->get($listener);
                    }
                    $listener->$eventName($eventArgs);
                }
                $this->initialized[$eventName] = true;
            }
        }

ContainerAwareEventManager->dispatchEvent('postPersist', object(LifecycleEventArgs)) in vendor/doctrine/orm/lib/Doctrine/ORM/Event/ListenersInvoker.php (line 117)

                    $instance->$method($entity, $event);
                }
            }
            if ($invoke & self::INVOKE_MANAGER) {
                $this->eventManager->dispatchEvent($eventName, $event);
            }
        }
    }

ListenersInvoker->invoke(object(ClassMetadata), 'postPersist', object(Box), object(LifecycleEventArgs), 4) in vendor/doctrine/orm/lib/Doctrine/ORM/UnitOfWork.php (line 1103)

                    }
                }
            }
            foreach ($entities as $entity) {
                $this->listenersInvoker->invoke($class, Events::postPersist, $entity, new LifecycleEventArgs($entity, $this->em), $invoke);
            }
        }
        /**
         * @param object $entity

UnitOfWork->executeInserts(object(ClassMetadata)) in vendor/doctrine/orm/lib/Doctrine/ORM/UnitOfWork.php (line 386)

                    $this->getCollectionPersister($collectionToDelete->getMapping())->delete($collectionToDelete);
                }
                if ($this->entityInsertions) {
                    foreach ($commitOrder as $class) {
                        $this->executeInserts($class);
                    }
                }
                if ($this->entityUpdates) {
                    foreach ($commitOrder as $class) {

UnitOfWork->commit(null) in vendor/doctrine/orm/lib/Doctrine/ORM/EntityManager.php (line 359)

         */
        public function flush($entity = null)
        {
            $this->errorIfClosed();
            $this->unitOfWork->commit($entity);
        }
        /**
         * Finds an Entity by its identifier.
         *

EntityManager->flush() in src/AppBundle/Handler/Box.php (line 129)

                }
                throw new ValidationException("Validation errors: " . $message);
            }
            $this->om->persist($box);
            $this->om->flush();
            return $box;
        }
        /**

Box->createFromObject(object(Box)) in src/AppBundle/Controller/BoxController.php (line 108)

                $box
            );
            $form->handleRequest($request);
            if ($form->isSubmitted() && $form->isValid()) {
                $this->boxHandler->createFromObject($box);
                $this->addFlash('notice', 'box.create.success');
                $request->getSession()->set('last_created_box_domain', $box->getDomain()->getName());
                return $this->redirectToRoute('box_show', ['id' => $box->getId()]);

BoxController->newAction(object(Request)) in vendor/symfony/symfony/src/Symfony/Component/HttpKernel/HttpKernel.php (line 151)

            $this->dispatcher->dispatch(KernelEvents::CONTROLLER_ARGUMENTS, $event);
            $controller = $event->getController();
            $arguments = $event->getArguments();
            // call controller
            $response = \call_user_func_array($controller, $arguments);
            // view
            if (!$response instanceof Response) {
                $event = new GetResponseForControllerResultEvent($this, $request, $type, $response);
                $this->dispatcher->dispatch(KernelEvents::VIEW, $event);

HttpKernel->handleRaw(object(Request), 1) in vendor/symfony/symfony/src/Symfony/Component/HttpKernel/HttpKernel.php (line 68)

        public function handle(Request $request, $type = HttpKernelInterface::MASTER_REQUEST, $catch = true)
        {
            $request->headers->set('X-Php-Ob-Level', ob_get_level());
            try {
                return $this->handleRaw($request, $type);
            } catch (\Exception $e) {
                if ($e instanceof RequestExceptionInterface) {
                    $e = new BadRequestHttpException($e->getMessage(), $e);
                }
                if (false === $catch) {

HttpKernel->handle(object(Request), 1, true) in vendor/symfony/symfony/src/Symfony/Component/HttpKernel/Kernel.php (line 200)

            $this->boot();
            ++$this->requestStackSize;
            $this->resetServices = true;
            try {
                return $this->getHttpKernel()->handle($request, $type, $catch);
            } finally {
                --$this->requestStackSize;
            }
        }

Kernel->handle(object(Request)) in web/app.php (line 16)

    //$kernel = new AppCache($kernel);
    // When using the HttpCache, you need to call the method in your front controller instead of relying on the configuration parameter
    //Request::enableHttpMethodParameterOverride();
    $request = Request::createFromGlobals();
    $response = $kernel->handle($request);
    $response->send();
    $kernel->terminate($request, $response);

EDIT: Thankfully there were no other email accounts setup yet on that domain, so I was able to delete the entire virtual domain and start over.

Comments (7)

  1. SB

    I have the same issue as Greg does -

    Cause: Delete an existing mailbox, create a 'redirect' using the original mailbox name.

  2. SH repo owner

    If you wait couple seconds/minutes it should solve itself. There is filesystem cache hanging at fpm thread...

  3. SB

    SH - You are correct, this has worked when I tried it now. It was an empty account made as mailbox by mistake, so I thought it would have nothing there to remove.

    Next time I will remember this, thank you.

  4. Log in to comment