"use strict";
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.WorkflowEndHandler = void 0;
const di_1 = require("@n8n/di");
const api_1 = require("@opentelemetry/api");
const otel_constants_1 = require("../otel.constants");
let WorkflowEndHandler = class WorkflowEndHandler {
    handle(ctx, spans) {
        const span = spans.removeWorkflow(ctx.executionId);
        if (!span)
            return;
        const attributes = {
            [otel_constants_1.ATTR.EXECUTION_MODE]: ctx.runData.mode,
            [otel_constants_1.ATTR.EXECUTION_STATUS]: ctx.runData.status,
            [otel_constants_1.ATTR.EXECUTION_IS_RETRY]: ctx.runData.mode === 'retry',
        };
        if (ctx.retryOf) {
            attributes[otel_constants_1.ATTR.EXECUTION_RETRY_OF] = ctx.retryOf;
        }
        span.setAttributes(attributes);
        if (['error', 'crashed'].includes(ctx.runData.status)) {
            span.setStatus({ code: api_1.SpanStatusCode.ERROR });
            const error = ctx.runData.data.resultData.error;
            if (error) {
                span.setAttribute(otel_constants_1.ATTR.EXECUTION_ERROR_TYPE, this.getErrorType(error));
            }
        }
        else {
            span.setStatus({ code: api_1.SpanStatusCode.OK });
        }
        span.end();
        this.endDanglingNodeSpans(ctx.executionId, spans);
        spans.cleanup(ctx.executionId);
    }
    endDanglingNodeSpans(executionId, spans) {
        for (const span of spans.findUnendedNodeSpans(executionId)) {
            span.setAttribute(otel_constants_1.ATTR.NODE_TERMINATION_REASON, 'workflow_cancelled');
            span.setStatus({ code: api_1.SpanStatusCode.ERROR });
            span.end();
        }
    }
    getErrorType(error) {
        if (!isRecord(error))
            return 'UnknownError';
        const errorName = error.name;
        if (typeof errorName === 'string' && errorName.trim() !== '')
            return errorName;
        const constructor = error.constructor;
        if (typeof constructor !== 'function')
            return 'UnknownError';
        const constructorName = constructor.name;
        if (typeof constructorName === 'string' &&
            constructorName.trim() !== '' &&
            constructorName !== 'Object') {
            return constructorName;
        }
        return 'UnknownError';
    }
};
exports.WorkflowEndHandler = WorkflowEndHandler;
exports.WorkflowEndHandler = WorkflowEndHandler = __decorate([
    (0, di_1.Service)()
], WorkflowEndHandler);
function isRecord(value) {
    return typeof value === 'object' && value !== null;
}
//# sourceMappingURL=workflow-end.handler.js.map