Twig \ Error \ RuntimeError
An exception has been thrown during the rendering of a template ("Product not found") in "mod_order_product.html.twig" at line 9.
Previous exceptions
  • Product not found (0)
Twig\Error\RuntimeError thrown with message "An exception has been thrown during the rendering of a template ("Product not found") in "mod_order_product.html.twig" at line 9." Stacktrace: #16 Twig\Error\RuntimeError in /var/www/themes/tide/html/mod_order_product.html.twig:9 #15 Box\Mod\Order\Controller\Client:get_configure_product_by_slug in [internal]:0 #14 FOSSBilling\Exception in /var/www/modules/Product/Api/Guest.php:82 #13 Box\Mod\Product\Api\Guest:get in /var/www/library/Api/Handler.php:113 #12 Api_Handler:__call in /var/www/vendor/twig/twig/src/Extension/CoreExtension.php:1918 #11 Twig\Extension\CoreExtension:getAttribute in /var/www/data/cache/13/13317a96536d66fc268515c0c08bf998.php:60 #10 __TwigTemplate_b9e294018fba2dfb2b88a4a5a5084d75:doDisplay in /var/www/vendor/twig/twig/src/Template.php:411 #9 Twig\Template:yield in /var/www/vendor/twig/twig/src/Template.php:366 #8 Twig\Template:display in /var/www/vendor/twig/twig/src/Template.php:381 #7 Twig\Template:render in /var/www/vendor/twig/twig/src/TemplateWrapper.php:51 #6 Twig\TemplateWrapper:render in /var/www/library/Box/AppClient.php:96 #5 Box_AppClient:render in /var/www/modules/Order/Controller/Client.php:52 #4 Box\Mod\Order\Controller\Client:get_configure_product_by_slug in [internal]:0 #3 ReflectionMethod:invokeArgs in /var/www/library/Box/App.php:268 #2 Box_App:executeShared in /var/www/library/Box/App.php:399 #1 Box_App:processRequest in /var/www/library/Box/App.php:183 #0 Box_App:run in /var/www/index.php:115
Stack frames (17)
16
Twig\Error\RuntimeError
/themes/tide/html/mod_order_product.html.twig:9
15
Box\Mod\Order\Controller\Client get_configure_product_by_slug
[internal]:0
14
FOSSBilling\Exception
/modules/Product/Api/Guest.php:82
13
Box\Mod\Product\Api\Guest get
/library/Api/Handler.php:113
12
Api_Handler __call
/vendor/twig/twig/src/Extension/CoreExtension.php:1918
11
Twig\Extension\CoreExtension getAttribute
/data/cache/13/13317a96536d66fc268515c0c08bf998.php:60
10
__TwigTemplate_b9e294018fba2dfb2b88a4a5a5084d75 doDisplay
/vendor/twig/twig/src/Template.php:411
9
Twig\Template yield
/vendor/twig/twig/src/Template.php:366
8
Twig\Template display
/vendor/twig/twig/src/Template.php:381
7
Twig\Template render
/vendor/twig/twig/src/TemplateWrapper.php:51
6
Twig\TemplateWrapper render
/library/Box/AppClient.php:96
5
Box_AppClient render
/modules/Order/Controller/Client.php:52
4
Box\Mod\Order\Controller\Client get_configure_product_by_slug
[internal]:0
3
ReflectionMethod invokeArgs
/library/Box/App.php:268
2
Box_App executeShared
/library/Box/App.php:399
1
Box_App processRequest
/library/Box/App.php:183
0
Box_App run
/index.php:115
/var/www/themes/tide/html/mod_order_product.html.twig
{% set url = request._url|default('') %}
{% set parts = url|split('/') %}
{% set last = parts|last %}
 
{% set is_id = last matches '/^\\d+$/' %}
 
{# if slug, try to fetch product by slug and use its id #}
{% if not is_id %}
  {% set p = guest.product_get({'slug': last}) %}
  {% set order_id = p.id|default(null) %}
{% else %}
  {% set order_id = last %}
{% endif %}
 
{% block js %}
{% autoescape "js" %}
<script>
(function () {
  var orderId = {{ order_id is not null ? order_id : 'null' }};
 
  if (orderId !== null) {
    window.location.replace('/orderbutton?order=' + orderId);
  } else {
    window.location.replace('/');
  }
})();
</script>
{% endautoescape %}
{% endblock %}
Arguments
  1. "An exception has been thrown during the rendering of a template ("Product not found") in "mod_order_product.html.twig" at line 9."
    
[internal]
/var/www/modules/Product/Api/Guest.php
     * @throws \FOSSBilling\Exception
     */
    public function get($data)
    {
        if (!isset($data['id']) && !isset($data['slug'])) {
            throw new \FOSSBilling\Exception('Product ID or slug is missing');
        }
 
        $id = $data['id'] ?? null;
        $slug = $data['slug'] ?? null;
 
        $service = $this->getService();
        if ($id) {
            $model = $service->findOneActiveById((int) $id);
        } else {
            $model = $service->findOneActiveBySlug($slug);
        }
 
        if (!$model instanceof \Model_Product) {
            throw new \FOSSBilling\Exception('Product not found');
        }
 
        return $service->toApiArray($model);
    }
 
    /**
     * Get paginated list of product categories.
     *
     * @return array
     */
    public function category_get_list($data)
    {
        $data['status'] = 'enabled';
        $service = $this->getService();
 
        [$sql, $params] = $service->getProductCategorySearchQuery($data);
        $pager = $this->getDi()['pager']->getPaginatedResultSet($sql, $params, PaginationOptions::fromArray($data));
 
        foreach ($pager['list'] as $key => $item) {
            $category = $this->getDi()['db']->getExistingModelById('ProductCategory', $item['id'], 'Product category not found');
Arguments
  1. "Product not found"
    
Exception message: Product not found
/var/www/library/Api/Handler.php
        $api->setDi($this->di);
        $api->setMod($bb_mod);
        $api->setIdentity($this->identity);
        $api->setIp($this->getDi()['request']->getClientIp());
        if ($bb_mod->hasService()) {
            $api->setService($this->getDi()['mod_service']($mod));
        }
 
        if (!method_exists($api, $method_name) || !is_callable([$api, $method_name])) {
            $reflector = new ReflectionClass($api);
            if (!$reflector->hasMethod('__call')) {
                throw new FOSSBilling\Exception(':type API call :method does not exist in module :module', [':type' => ucfirst((string) $this->type), ':method' => $method_name, ':module' => $mod], 740);
            }
        }
 
        $data = is_array($arguments) ? $arguments : [];
 
        $this->validateRequiredParams($api, $method_name, $data);
 
        return $api->{$method_name}($arguments);
    }
 
    /**
     * Validate required parameters for an API method using attributes.
     *
     * @param Api_Abstract $api         The API instance
     * @param string       $method_name The method name
     * @param array        $data        The data array passed to the method
     *
     * @throws FOSSBilling\InformationException If required parameters are missing
     */
    public function validateRequiredParams(Api_Abstract $api, string $method_name, array $data): void
    {
        try {
            $reflection = new ReflectionMethod($api, $method_name);
        } catch (ReflectionException) {
            // Method doesn't exist, skip validation
            return;
        }
 
/var/www/vendor/twig/twig/src/Extension/CoreExtension.php
                if ($isDefinedTest) {
                    return false;
                }
 
                if ($propertyNotAllowedError) {
                    throw $propertyNotAllowedError;
                }
 
                throw $e;
            }
        }
 
        if ($isDefinedTest) {
            return true;
        }
 
        // Some objects throw exceptions when they have __call, and the method we try
        // to call is not supported. If ignoreStrictCheck is true, we should return null.
        try {
            $ret = $object->$method(...$arguments);
        } catch (\BadMethodCallException $e) {
            if ($call && ($ignoreStrictCheck || !$env->isStrictVariables())) {
                return;
            }
            throw $e;
        }
 
        return $ret;
    }
 
    /**
     * Returns the values from a single column in the input array.
     *
     * <pre>
     *  {% set items = [{ 'fruit' : 'apple'}, {'fruit' : 'orange' }] %}
     *
     *  {% set fruits = items|column('fruit') %}
     *
     *  {# fruits now contains ['apple', 'orange'] #}
     * </pre>
/var/www/data/cache/13/13317a96536d66fc268515c0c08bf998.php
        $macros = $this->macros;
        // line 1
        $context["url"] = ((CoreExtension::getAttribute($this->env, $this->source, ($context["request"] ?? null), "_url", [], "any", true, true, false, 1)) ? (Twig\Extension\CoreExtension::default(CoreExtension::getAttribute($this->env, $this->source, ($context["request"] ?? null), "_url", [], "any", false, false, false, 1), "")) : (""));
        // line 2
        $context["parts"] = Twig\Extension\CoreExtension::split($this->env->getCharset(), ($context["url"] ?? null), "/");
        // line 3
        $context["last"] = Twig\Extension\CoreExtension::last($this->env->getCharset(), ($context["parts"] ?? null));
        // line 4
        yield "
";
        // line 5
        $context["is_id"] = CoreExtension::matches("/^\\d+\$/", ($context["last"] ?? null));
        // line 6
        yield "
";
        // line 8
        if ((($tmp =  !($context["is_id"] ?? null)) && $tmp instanceof Markup ? (string) $tmp : $tmp)) {
            // line 9
            yield "  ";
            $context["p"] = CoreExtension::getAttribute($this->env, $this->source, ($context["guest"] ?? null), "product_get", [["slug" => ($context["last"] ?? null)]], "method", false, false, false, 9);
            // line 10
            yield "  ";
            $context["order_id"] = ((CoreExtension::getAttribute($this->env, $this->source, ($context["p"] ?? null), "id", [], "any", true, true, false, 10)) ? (Twig\Extension\CoreExtension::default(CoreExtension::getAttribute($this->env, $this->source, ($context["p"] ?? null), "id", [], "any", false, false, false, 10), null)) : (null));
        } else {
            // line 12
            yield "  ";
            $context["order_id"] = ($context["last"] ?? null);
        }
        // line 14
        yield "
";
        // line 15
        yield from $this->unwrap()->yieldBlock('js', $context, $blocks);
        yield from [];
    }
 
    /**
     * @return iterable<null|scalar|\Stringable>
     */
    public function block_js(array $context, array $blocks = []): iterable
/var/www/vendor/twig/twig/src/Template.php
 
        $content = '';
        foreach ($this->yield($context) as $data) {
            $content .= $data;
        }
 
        return $content;
    }
 
    /**
     * @return iterable<scalar|\Stringable|null>
     */
    public function yield(array $context, array $blocks = []): iterable
    {
        $context += $this->env->getGlobals();
        $blocks = array_merge($this->blocks, $blocks);
 
        try {
            $this->ensureSecurityChecked();
            yield from $this->doDisplay($context, $blocks);
        } catch (Error $e) {
            if (!$e->getSourceContext()) {
                $e->setSourceContext($this->getSourceContext());
            }
 
            // this is mostly useful for \Twig\Error\LoaderError exceptions
            // see \Twig\Error\LoaderError
            if (-1 === $e->getTemplateLine()) {
                $e->guess();
            }
 
            throw $e;
        } catch (\Throwable $e) {
            $e = new RuntimeError(\sprintf('An exception has been thrown during the rendering of a template ("%s").', $e->getMessage()), -1, $this->getSourceContext(), $e);
            $e->guess();
 
            throw $e;
        }
    }
 
/var/www/vendor/twig/twig/src/Template.php
    {
        return $this;
    }
 
    /**
     * Returns all blocks.
     *
     * This method is for internal use only and should never be called
     * directly.
     *
     * @return array An array of blocks
     */
    public function getBlocks(): array
    {
        return $this->blocks;
    }
 
    public function display(array $context, array $blocks = []): void
    {
        foreach ($this->yield($context, $blocks) as $data) {
            echo $data;
        }
    }
 
    public function render(array $context): string
    {
        if (!$this->useYield) {
            $level = ob_get_level();
            if ($this->env->isDebug()) {
                ob_start();
            } else {
                ob_start(static function () { return ''; });
            }
            try {
                $this->display($context);
            } catch (\Throwable $e) {
                while (ob_get_level() > $level) {
                    ob_end_clean();
                }
 
/var/www/vendor/twig/twig/src/Template.php
    }
 
    public function display(array $context, array $blocks = []): void
    {
        foreach ($this->yield($context, $blocks) as $data) {
            echo $data;
        }
    }
 
    public function render(array $context): string
    {
        if (!$this->useYield) {
            $level = ob_get_level();
            if ($this->env->isDebug()) {
                ob_start();
            } else {
                ob_start(static function () { return ''; });
            }
            try {
                $this->display($context);
            } catch (\Throwable $e) {
                while (ob_get_level() > $level) {
                    ob_end_clean();
                }
 
                throw $e;
            }
 
            return ob_get_clean();
        }
 
        $content = '';
        foreach ($this->yield($context) as $data) {
            $content .= $data;
        }
 
        return $content;
    }
 
    /**
/var/www/vendor/twig/twig/src/TemplateWrapper.php
 
    /**
     * @return iterable<scalar|\Stringable|null>
     */
    public function stream(array $context = []): iterable
    {
        yield from $this->template->yield($context);
    }
 
    /**
     * @return iterable<scalar|\Stringable|null>
     */
    public function streamBlock(string $name, array $context = []): iterable
    {
        yield from $this->template->yieldBlock($name, $context);
    }
 
    public function render(array $context = []): string
    {
        return $this->template->render($context);
    }
 
    /**
     * @return void
     */
    public function display(array $context = [])
    {
        // using func_get_args() allows to not expose the blocks argument
        // as it should only be used by internal code
        $this->template->display($context, \func_get_args()[1] ?? []);
    }
 
    public function hasBlock(string $name, array $context = []): bool
    {
        return $this->template->hasBlock($name, $context);
    }
 
    /**
     * @return string[] An array of defined template block names
     */
/var/www/library/Box/AppClient.php
        $this->di['logger']->setChannel('routing')->info($e->getMessage());
 
        return $this->errorResponse($e, 404);
    }
 
    /**
     * @param string $fileName
     */
    #[Override]
    public function render($fileName, $variableArray = [], $ext = 'html.twig'): string
    {
        try {
            $template = $this->getTwig()->load(Path::changeExtension($fileName, $ext));
        } catch (Twig\Error\LoaderError $e) {
            $this->di['logger']->setChannel('routing')->info($e->getMessage());
 
            throw new FOSSBilling\InformationException('Page not found', null, 404);
        }
 
        return $template->render($variableArray);
    }
 
    /**
     * Get Twig environment for client area.
     */
    protected function getTwig(): Twig\Environment
    {
        $twigFactory = $this->di['twig_factory'];
 
        return $twigFactory->createClientEnvironment($this->debugBar);
    }
}
 
/var/www/modules/Order/Controller/Client.php
        $app->get('/order/:id', 'get_configure_product', ['id' => '[0-9]+'], static::class);
        $app->get('/order/:slug', 'get_configure_product_by_slug', ['slug' => '[a-z0-9-]+'], static::class);
        $app->get('/order/service/manage/:id', 'get_order', ['id' => '[0-9]+'], static::class);
    }
 
    public function get_products(\Box_App $app): string
    {
        return $app->render('mod_order_index');
    }
 
    public function get_configure_product_by_slug(\Box_App $app, $slug): string
    {
        $api = $this->di['api_guest'];
        $product = $api->product_get(['slug' => $slug]);
        $tpl = 'mod_service' . $product['type'] . '_order';
        if ($api->system_template_exists(['file' => $tpl . '.html.twig'])) {
            return $app->render($tpl, ['product' => $product]);
        }
 
        return $app->render('mod_order_product', ['product' => $product]);
    }
 
    public function get_configure_product(\Box_App $app, $id): string
    {
        $api = $this->di['api_guest'];
        $product = $api->product_get(['id' => $id]);
        $tpl = 'mod_service' . $product['type'] . '_order';
        if ($api->system_template_exists(['file' => $tpl . '.html.twig'])) {
            return $app->render($tpl, ['product' => $product]);
        }
 
        return $app->render('mod_order_product', ['product' => $product]);
    }
 
    public function get_orders(\Box_App $app): string
    {
        $this->di['is_client_logged'];
 
        return $app->render('mod_order_list');
    }
[internal]
/var/www/library/Box/App.php
 
        $timeCollector->startMeasure('executeShared', 'Reflecting module controller (shared mapping)');
        $class = new $classname();
        if ($class instanceof InjectionAwareInterface) {
            $class->setDi($this->di);
        }
        $reflection = new ReflectionMethod($class::class, $methodName);
        $args = [];
        $args[] = $this; // first param always app instance
 
        foreach ($reflection->getParameters() as $param) {
            if (isset($params[$param->name])) {
                $args[$param->name] = $params[$param->name];
            } elseif ($param->isDefaultValueAvailable()) {
                $args[$param->name] = $param->getDefaultValue();
            }
        }
        $timeCollector->stopMeasure('executeShared');
 
        return $reflection->invokeArgs($class, $args);
    }
 
    protected function execute($methodName, $params, $classname = null): mixed
    {
        /** @var TimeDataCollector $timeCollector */
        $timeCollector = $this->debugBar->getCollector('time');
 
        $timeCollector->startMeasure('execute', 'Reflecting module controller');
 
        $reflection = new ReflectionMethod(static::class, $methodName);
        $args = [];
 
        foreach ($reflection->getParameters() as $param) {
            if (isset($params[$param->name])) {
                $args[$param->name] = $params[$param->name];
            } elseif ($param->isDefaultValueAvailable()) {
                $args[$param->name] = $param->getDefaultValue();
            }
        }
 
/var/www/library/Box/App.php
 
                    return $apiController->renderJson(null, $exc);
                }
 
                return $this->renderResponse('mod_system_maintenance', [], 503);
            }
        }
 
        /** @var TimeDataCollector $timeCollector */
        $timeCollector = $this->debugBar->getCollector('time');
 
        $timeCollector->startMeasure('sharedMapping', 'Checking shared mappings');
        $sharedCount = count($this->shared);
        for ($i = 0; $i < $sharedCount; ++$i) {
            $mapping = $this->shared[$i];
            $url = new Box_UrlHelper($mapping[0], $mapping[1], $mapping[3], $this->url, $this->getRequest()->getMethod());
            if ($url->match) {
                $timeCollector->stopMeasure('sharedMapping');
 
                return $this->normalizeResponse($this->executeShared($mapping[4], $mapping[2], $url->params));
            }
        }
        $timeCollector->stopMeasure('sharedMapping');
 
        // this class mappings
        $timeCollector->startMeasure('mapping', 'Checking mappings');
        $mappingsCount = count($this->mappings);
        for ($i = 0; $i < $mappingsCount; ++$i) {
            $mapping = $this->mappings[$i];
            $url = new Box_UrlHelper($mapping[0], $mapping[1], $mapping[3], $this->url, $this->getRequest()->getMethod());
            if ($url->match) {
                $timeCollector->stopMeasure('mapping');
 
                return $this->normalizeResponse($this->execute($mapping[2], $url->params));
            }
        }
        $timeCollector->stopMeasure('mapping');
 
        $e = new FOSSBilling\InformationException('Page :url not found', [':url' => $this->url], 404);
 
/var/www/library/Box/App.php
 
    public function run(): Response
    {
        /** @var TimeDataCollector $timeCollector */
        $timeCollector = $this->debugBar->getCollector('time');
 
        try {
            $timeCollector->startMeasure('registerModule', 'Registering module routes');
            $this->registerModule();
            $timeCollector->stopMeasure('registerModule');
 
            $timeCollector->startMeasure('init', 'Initializing the app');
            $this->init();
            $timeCollector->stopMeasure('init');
 
            $timeCollector->startMeasure('checkperm', 'Checking access to module');
            $this->checkPermission();
            $timeCollector->stopMeasure('checkperm');
 
            return $this->processRequest();
        } catch (AuthenticationRequiredException $e) {
            if ($e->getArea() === 'admin') {
                $this->di['set_return_uri'];
 
                return new RedirectResponse($this->di['url']->adminLink('staff/login'));
            }
 
            $this->di['set_return_uri'];
 
            return new RedirectResponse($this->di['url']->link('login'));
        } catch (EmailValidationRequiredException) {
            return new RedirectResponse($this->di['url']->link('client/profile'));
        } catch (HttpResponseException $e) {
            return $e->getResponse();
        }
    }
 
    /**
     * @param string $path
     */
/var/www/index.php
$timeCollector?->stopMeasure('translate');
 
// If HTTP error code has been passed, handle it.
if (!is_null($http_err_code)) {
    $http_err_code = intval($http_err_code);
    switch ($http_err_code) {
        case 404:
            $e = new FOSSBilling\Exception('Page :url not found', [':url' => $url], 404);
            $app->show404($e)->send();
 
            break;
        default:
            $e = new FOSSBilling\Exception('HTTP Error :err_code occurred while attempting to load :url', [':err_code' => $http_err_code, ':url' => $url], $http_err_code);
            (new Response($app->render('error', ['exception' => $e]), $http_err_code))->send();
    }
    exit;
}
 
// If no HTTP error passed, run the app.
$app->run()->send();
exit;
 

Environment & details:

Key Value
PHP Version
"8.5.7"
Error code
0
Instance ID
"XXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXXX"
Key Value
_url
"/order/domain-checker"
empty
empty
empty
Key Value
csrf_token
"84e40e97ce7905ef5892ebaff6b66954527cd15fb7d9f866d94f39ae95836bac"
Key Value
USER
"www-data"
HOME
"/var/www"
HTTP_ACCEPT_ENCODING
"gzip, br, zstd, deflate"
HTTP_USER_AGENT
"Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; ClaudeBot/1.0; +claudebot@anthropic.com)"
HTTP_ACCEPT
"*/*"
HTTP_HOST
"cp.kovil.re"
REDIRECT_STATUS
"200"
SERVER_NAME
"cp.kovil.re"
SERVER_PORT
"443"
SERVER_ADDR
"208.85.20.19"
REMOTE_USER
""
REMOTE_PORT
"6390"
REMOTE_ADDR
"216.73.216.179"
SERVER_SOFTWARE
"nginx/1.24.0"
GATEWAY_INTERFACE
"CGI/1.1"
HTTPS
"on"
REQUEST_SCHEME
"https"
SERVER_PROTOCOL
"HTTP/2.0"
DOCUMENT_ROOT
"/var/www"
DOCUMENT_URI
"/index.php"
REQUEST_URI
"/order/domain-checker"
SCRIPT_NAME
"/index.php"
CONTENT_LENGTH
""
CONTENT_TYPE
""
REQUEST_METHOD
"GET"
QUERY_STRING
"_url=/order/domain-checker"
SCRIPT_FILENAME
"/var/www/index.php"
PATH_INFO
""
FCGI_ROLE
"RESPONDER"
PHP_SELF
"/index.php"
REQUEST_TIME_FLOAT
1781184048.269
REQUEST_TIME
1781184048
empty
0. Whoops\Handler\PrettyPageHandler