Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

experimental: map based classifier #2

Open
kamilsk opened this issue Apr 29, 2022 · 0 comments
Open

experimental: map based classifier #2

kamilsk opened this issue Apr 29, 2022 · 0 comments
Assignees

Comments

@kamilsk
Copy link
Member

kamilsk commented Apr 29, 2022

class ActionContext
{
    public function __construct(
        public readonly Flow $flow,
        public readonly Severity $severity,
        public readonly ?bool $useErrorMessage = null,
        public readonly ?string $message = null,
        public readonly ?string $metric = null,
    ) {
    }
}



class BaseClassifier implements \OctoLab\Observer\Payload\Classifier
{
    private array $actions = [];

    public function extend(string $fqcn, ActionContext $actionContext): void
    {
        if (!class_exists($fqcn) && !interface_exists($fqcn)) {
            throw new UnknownClassnameException($fqcn);
        }

        $this->actions[$fqcn] = $actionContext;
    }

    public function classify(\Throwable $error): Type\Action
    {
        return match (true) {
            $this->extendedActionExists($error) => $this->getExtendedAction($error),
            default => new Type\Action(
                $error,
                Type\Flow::throw,
                severity: Type\Severity::Error,
                message: $error->getMessage(),
                metric: Metrics::NOT_CLASSIFIED_ERROR,
            ),
        };
    }

    private function extendedActionExists(\Throwable $error): bool
    {
        return $this->getActionContext($error) !== null;
    }

    private function getActionContext(\Throwable $error): ?ActionContext
    {
        if (isset($this->actions[$error::class])) {
            return $this->actions[$error::class];
        }

        foreach (class_implements($error) as $interfaceName) {
            if (isset($this->actions[$interfaceName])) {
                return $this->actions[$interfaceName];
            }
        }

        return null;
    }

    private function getExtendedAction(\Throwable $error): Type\Action
    {
        $actionContext = $this->getActionContext($error);

        return new Type\Action(
            $error,
            $actionContext->flow,
            $actionContext->severity,
            $actionContext->useErrorMessage ? $error->getMessage() : $actionContext->message,
            $actionContext->metric,
        );
    }
}


class DomainClassifier implements \OctoLab\Observer\Payload\Classifier
{
    public function __construct(private BaseClassifier $classifier)
    {
        $this->classifier->extend(
            DomainException\Exception::class,
            new ActionContext(
                flow: Type\Flow::ignore,
                severity: Type\Severity::Info,
                useErrorMessage: true,
                metric: Metrics::GHERKIN_PARSER_ERROR,
            ),
        );
    }

    public function classify(\Throwable $error): Type\Action
    {
        return $this->classifier->classify($error);
    }
}
@kamilsk kamilsk added the help wanted Extra attention is needed label Apr 29, 2022
@kamilsk kamilsk self-assigned this Apr 29, 2022
@kamilsk kamilsk removed the help wanted Extra attention is needed label Apr 29, 2022
@kamilsk kamilsk changed the title experimental: experimental: map based classifier Apr 29, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant