Skip to content

Commit

Permalink
feat: Split deployment failure messages. (#10060) (#10063)
Browse files Browse the repository at this point in the history
(cherry picked from commit 73dda48)

Co-authored-by: armory-abedonik <[email protected]>
  • Loading branch information
mergify[bot] and armory-abedonik authored Nov 21, 2023
1 parent e51a58b commit 43436ee
Show file tree
Hide file tree
Showing 5 changed files with 61 additions and 31 deletions.
1 change: 1 addition & 0 deletions packages/core/src/domain/IOrchestratedItem.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ export interface IOrchestratedItem extends ITimedItem {
getValueFor: (k: string) => any;
originalStatus: string;
status: string;
failureMessages: string[];
failureMessage: string;
isBuffered: boolean;
isCompleted: boolean;
Expand Down
34 changes: 21 additions & 13 deletions packages/core/src/orchestratedItem/orchestratedItem.transformer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,11 @@ export class OrchestratedItemTransformer {
item.originalStatus = item.status;

Object.defineProperties(item, {
failureMessages: {
get: (): string[] => this.getFailureMessages(item),
},
failureMessage: {
get: (): string => this.mergeExceptions(item),
get: (): string => this.getFailureMessagesAsString(item),
},
isCompleted: {
get: (): boolean => ['SUCCEEDED', 'SKIPPED'].includes(item.status),
Expand Down Expand Up @@ -131,19 +134,23 @@ export class OrchestratedItemTransformer {
});
}

private static mergeExceptions(item: any): string | null {
const exceptions = [
this.getCustomException(item),
this.getGeneralException(item),
this.getOrchestrationException(item),
].filter((it) => !!it);
private static getFailureMessagesAsString(item: any): string | null {
const exceptions = this.getFailureMessages(item);
if (exceptions.length === 0) {
return null;
}
return exceptions.join('\n\n');
}

private static getOrchestrationException(task: ITask): string {
private static getFailureMessages(task: ITask): string[] {
return [
this.getCustomExceptionMessage(task),
...this.getGeneralExceptionMessages(task),
this.getOrchestrationExceptionMessage(task),
].filter((it) => !!it);
}

private static getOrchestrationExceptionMessage(task: ITask): string {
const katoTasks: any[] = task.getValueFor('kato.tasks');
if (katoTasks && katoTasks.length) {
const failedTask: any = katoTasks.find((t) => t.status && t.status.failed);
Expand Down Expand Up @@ -190,7 +197,7 @@ export class OrchestratedItemTransformer {
return null;
}

private static getCustomException(task: ITask): string {
private static getCustomExceptionMessage(task: ITask): string {
const generalException: any = task.getValueFor('exception');
if (generalException) {
if (generalException.exceptionType && generalException.exceptionType === 'LockFailureException') {
Expand All @@ -200,16 +207,17 @@ export class OrchestratedItemTransformer {
return null;
}

private static getGeneralException(task: ITask): string {
private static getGeneralExceptionMessages(task: ITask): string[] {
const generalException: any = task.getValueFor('exception');
if (generalException) {
const errors = (generalException.details?.errors ?? []).filter((m: any) => !!m);
if (errors.length) {
return errors.join('\n\n');
return errors;
}
return generalException.details?.error ?? null;

return generalException.details?.error ? [generalException.details.error] : [];
}
return null;
return [];
}

private static calculateRunningTime(item: IOrchestratedItem): () => number {
Expand Down
8 changes: 5 additions & 3 deletions packages/core/src/presentation/CollapsibleElement.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,11 @@ export const CollapsibleElement: React.FC<{ maxHeight: number }> = ({ children,
setIsOverflowing(contentRef.current.offsetHeight < contentRef.current.scrollHeight);
}, []);

React.useEffect(() => {
checkIsOverflowing();
}, [children, checkIsOverflowing]);
React.useLayoutEffect(() => {
setTimeout(() => {
checkIsOverflowing();
});
}, [checkIsOverflowing]);

React.useEffect(() => {
window.addEventListener('resize', checkIsOverflowing);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
.deploy-status .collapsible-element {
margin-bottom: 20px;

.alert {
margin-bottom: 0;
}

.content {
padding: 0;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@ import { get } from 'lodash';
import React from 'react';

import type { IExecutionDetailsSectionProps, IManifest } from '@spinnaker/core';
import { ExecutionDetailsSection, StageFailureMessage } from '@spinnaker/core';
import { CollapsibleElement, ExecutionDetailsSection, StageFailureMessage } from '@spinnaker/core';

import { ManifestStatus } from './ManifestStatus';
import type { IStageManifest } from '../../../../manifest/manifest.service';
import { KubernetesManifestService } from '../../../../manifest/manifest.service';

import './DeployStatus.less';

export interface IManifestSubscription {
id: string;
unsubscribe: () => void;
Expand Down Expand Up @@ -87,22 +89,28 @@ export class DeployStatus extends React.Component<IExecutionDetailsSectionProps,
const { name: sectionName, current: currentSection, stage } = this.props;
const manifests: IManifest[] = this.state.subscriptions.filter((sub) => !!sub.manifest).map((sub) => sub.manifest);
return (
<ExecutionDetailsSection name={sectionName} current={currentSection}>
<StageFailureMessage stage={stage} message={stage.failureMessage} />
{manifests && (
<div className="row">
<div className="col-md-12">
<div className="well alert alert-info">
{manifests.map((manifest) => {
const uid =
manifest.manifest.metadata.uid || KubernetesManifestService.manifestIdentifier(manifest.manifest);
return <ManifestStatus key={uid} manifest={manifest} account={stage.context.account} />;
})}
<div className="deploy-status">
<ExecutionDetailsSection name={sectionName} current={currentSection}>
{stage.failureMessages.map((failureMessage) => (
<CollapsibleElement key={failureMessage} maxHeight={150}>
<StageFailureMessage stage={stage} message={failureMessage} />
</CollapsibleElement>
))}
{!!manifests?.length && (
<div className="row">
<div className="col-md-12">
<div className="well alert alert-info">
{manifests.map((manifest) => {
const uid =
manifest.manifest.metadata.uid || KubernetesManifestService.manifestIdentifier(manifest.manifest);
return <ManifestStatus key={uid} manifest={manifest} account={stage.context.account} />;
})}
</div>
</div>
</div>
</div>
)}
</ExecutionDetailsSection>
)}
</ExecutionDetailsSection>
</div>
);
}
}

0 comments on commit 43436ee

Please sign in to comment.