/home/complianthowden/public_html/vendor/sentry/sentry-laravel/src/Sentry/Laravel/Integration.php
<?php

namespace Sentry\Laravel;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\LazyLoadingViolationException;
use Illuminate\Routing\Route;
use Sentry\EventHint;
use Sentry\EventId;
use Sentry\ExceptionMechanism;
use Sentry\Laravel\Features\Concerns\ResolvesEventOrigin;
use Sentry\SentrySdk;
use Sentry\Severity;
use Sentry\Tracing\TransactionSource;
use Throwable;
use Sentry\Breadcrumb;
use Sentry\Event;
use Sentry\Integration\IntegrationInterface;
use Sentry\State\Scope;

use function Sentry\addBreadcrumb;
use function Sentry\configureScope;
use function Sentry\getBaggage;
use function Sentry\getTraceparent;

class Integration implements IntegrationInterface
{
    /**
     * @var null|string
     */
    private static $transaction;

    /**
     * {@inheritdoc}
     */
    public function setupOnce(): void
    {
        Scope::addGlobalEventProcessor(static function (Event $event): Event {
            $self = SentrySdk::getCurrentHub()->getIntegration(self::class);

            if (!$self instanceof self) {
                return $event;
            }

            if (empty($event->getTransaction())) {
                $event->setTransaction(self::getTransaction());
            }

            return $event;
        });
    }

    /**
     * Adds a breadcrumb if the integration is enabled for Laravel.
     *
     * @param Breadcrumb $breadcrumb
     */
    public static function addBreadcrumb(Breadcrumb $breadcrumb): void
    {
        $self = SentrySdk::getCurrentHub()->getIntegration(self::class);

        if (!$self instanceof self) {
            return;
        }

        addBreadcrumb($breadcrumb);
    }

    /**
     * Configures the scope if the integration is enabled for Laravel.
     *
     * @param callable $callback
     */
    public static function configureScope(callable $callback): void
    {
        $self = SentrySdk::getCurrentHub()->getIntegration(self::class);

        if (!$self instanceof self) {
            return;
        }

        configureScope($callback);
    }

    /**
     * @return null|string
     */
    public static function getTransaction(): ?string
    {
        return self::$transaction;
    }

    /**
     * @param null|string $transaction
     */
    public static function setTransaction(?string $transaction): void
    {
        self::$transaction = $transaction;
    }

    /**
     * Block until all async events are processed for the HTTP transport.
     *
     * @internal This is not part of the public API and is here temporarily until
     *  the underlying issue can be resolved, this method will be removed.
     */
    public static function flushEvents(): void
    {
        $client = SentrySdk::getCurrentHub()->getClient();

        if ($client !== null) {
            $client->flush();
        }
    }

    /**
     * Extract the readable name for a route and the transaction source for where that route name came from.
     *
     * @param \Illuminate\Routing\Route $route
     *
     * @return array{0: string, 1: \Sentry\Tracing\TransactionSource}
     *
     * @internal This helper is used in various places to extract meaningful info from a Laravel Route object.
     */
    public static function extractNameAndSourceForRoute(Route $route): array
    {
        return [
            '/' . ltrim($route->uri(), '/'),
            TransactionSource::route(),
        ];
    }

    /**
     * Extract the readable name for a Lumen route and the transaction source for where that route name came from.
     *
     * @param array $routeData The array of route data
     * @param string $path The path of the request
     *
     * @return array{0: string, 1: \Sentry\Tracing\TransactionSource}
     *
     * @internal This helper is used in various places to extract meaningful info from Lumen route data.
     */
    public static function extractNameAndSourceForLumenRoute(array $routeData, string $path): array
    {
        $routeUri = array_reduce(
            array_keys($routeData[2]),
            static function ($carry, $key) use ($routeData) {
                $search = '/' . preg_quote($routeData[2][$key], '/') . '/';

                // Replace the first occurrence of the route parameter value with the key name
                // This is by no means a perfect solution, but it's the best we can do with the data we have
                return preg_replace($search, "{{$key}}", $carry, 1);
            },
            $path
        );

        return [
            '/' . ltrim($routeUri, '/'),
            TransactionSource::route(),
        ];
    }

    /**
     * Retrieve the meta tags with tracing information to link this request to front-end requests.
     * This propagates the Dynamic Sampling Context.
     *
     * @return string
     */
    public static function sentryMeta(): string
    {
        return self::sentryTracingMeta() . self::sentryBaggageMeta();
    }

    /**
     * Retrieve the `sentry-trace` meta tag with tracing information to link this request to front-end requests.
     *
     * @return string
     */
    public static function sentryTracingMeta(): string
    {
        return sprintf('<meta name="sentry-trace" content="%s"/>', getTraceparent());
    }

    /**
     * Retrieve the `baggage` meta tag with information to link this request to front-end requests.
     * This propagates the Dynamic Sampling Context.
     *
     * @return string
     */
    public static function sentryBaggageMeta(): string
    {
        return sprintf('<meta name="baggage" content="%s"/>', getBaggage());
    }

    /**
     * Capture a unhandled exception and report it to Sentry.
     *
     * @param \Throwable $throwable
     *
     * @return \Sentry\EventId|null
     */
    public static function captureUnhandledException(Throwable $throwable): ?EventId
    {
        // We instruct users to call `captureUnhandledException` in their exception handler, however this does not mean
        // the exception was actually unhandled. Laravel has the `report` helper function that is used to report to a log
        // file or Sentry, but that means they are handled otherwise they wouldn't have been routed through `report`. So to
        // prevent marking those as "unhandled" we try and make an educated guess if the call to `captureUnhandledException`
        // came from the `report` helper and shouldn't be marked as "unhandled" even though the come to us here to be reported
        $handled = self::makeAnEducatedGuessIfTheExceptionMaybeWasHandled();

        $hint = EventHint::fromArray([
            'mechanism' => new ExceptionMechanism(ExceptionMechanism::TYPE_GENERIC, $handled),
        ]);

        return SentrySdk::getCurrentHub()->captureException($throwable, $hint);
    }

    /**
     * Returns a callback that can be passed to `Model::handleLazyLoadingViolationUsing` to report lazy loading violations to Sentry.
     *
     * @param callable|null $callback Optional callback to be called after the violation is reported to Sentry.
     *
     * @return callable
     */
    public static function lazyLoadingViolationReporter(?callable $callback = null): callable
    {
        return new class($callback) {
            use ResolvesEventOrigin;

            /** @var callable|null $callback */
            private $callback;

            public function __construct(?callable $callback)
            {
                $this->callback = $callback;
            }

            public function __invoke(Model $model, string $relation): void
            {
                // Laravel uses these checks itself to not throw an exception if the model doesn't exist or was just created
                // See: https://github.com/laravel/framework/blob/438d02d3a891ab4d73ffea2c223b5d37947b5e93/src/Illuminate/Database/Eloquent/Concerns/HasAttributes.php#L563
                if (!$model->exists || $model->wasRecentlyCreated) {
                    return;
                }

                SentrySdk::getCurrentHub()->withScope(function (Scope $scope) use ($model, $relation) {
                    $scope->setContext('violation', [
                        'model'    => get_class($model),
                        'relation' => $relation,
                        'origin'   => $this->resolveEventOrigin(),
                    ]);

                    SentrySdk::getCurrentHub()->captureEvent(
                        tap(Event::createEvent(), static function (Event $event) {
                            $event->setLevel(Severity::warning());
                        }),
                        EventHint::fromArray([
                            'exception' => new LazyLoadingViolationException($model, $relation),
                            'mechanism' => new ExceptionMechanism(ExceptionMechanism::TYPE_GENERIC, true),
                        ])
                    );
                });

                // Forward the violation to the next handler if there is one
                if ($this->callback !== null) {
                    call_user_func($this->callback, $model, $relation);
                }
            }
        };
    }

    /**
     * Try to make an educated guess if the call came from the Laravel `report` helper.
     *
     * @see https://github.com/laravel/framework/blob/008a4dd49c3a13343137d2bc43297e62006c7f29/src/Illuminate/Foundation/helpers.php#L667-L682
     *
     * @return bool
     */
    private static function makeAnEducatedGuessIfTheExceptionMaybeWasHandled(): bool
    {
        // We limit the amount of backtrace frames since it is very unlikely to be any deeper
        $trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 20);

        // We are looking for `$handler->report()` to be called from the `report()` function
        foreach ($trace as $frameIndex => $frame) {
            // We need a frame with a class and function defined, we can skip frames missing either
            if (!isset($frame['class'], $frame['function'])) {
                continue;
            }

            // Check if the frame was indeed `$handler->report()`
            if ($frame['type'] !== '->' || $frame['function'] !== 'report') {
                continue;
            }

            // Make sure we have a next frame, we could have reached the end of the trace
            if (!isset($trace[$frameIndex + 1])) {
                continue;
            }

            // The next frame should contain the call to the `report()` helper function
            $nextFrame = $trace[$frameIndex + 1];

            // If a class was set or the function name is not `report` we can skip this frame
            if (isset($nextFrame['class']) || !isset($nextFrame['function']) || $nextFrame['function'] !== 'report') {
                continue;
            }

            // If we reached this point we can be pretty sure the `report` function was called
            // and we can come to the educated conclusion the exception was indeed handled
            return true;
        }

        // If we reached this point we can be pretty sure the `report` function was not called
        return false;
    }
}
Customer Complaint Form | Howden Indonesia - Official Working Website

CUSTOMER COMPLAINT FORM

Please use this form to give us suggestions, compliments or complaints.
Click here to check complaint status.
Click here to show Term of Business Agreement
Howden


Notes: *.png, *.jpg, *.jpeg, *.pdf, *.doc, *.docx, *.xls, *.xlsx, *.ppt, *.pptx, *.eml are allowed, and size must be smaller than 5Mb.

Copyright © 2026 PT. Howden Insurance Brokers Indonesia. All rights reserved.
Authorised and regulated by Otoritas Jasa Keuangan (OJK).
Member of The Association of Indonesian Insurance & Reinsurance Brokers (APPARINDO).