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

Display additional failure information when sync is expanded and jump to relevant log line #12896

Merged
merged 20 commits into from
May 26, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions airbyte-api/src/main/openapi/config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3844,6 +3844,8 @@ components:
$ref: "#/components/schemas/AttemptFailureType"
externalMessage:
type: string
internalMessage:
type: string
stacktrace:
type: string
retryable:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,7 @@ private static AttemptFailureSummary getAttemptFailureSummary(final Attempt atte
.failureOrigin(Enums.convertTo(failure.getFailureOrigin(), AttemptFailureOrigin.class))
.failureType(Enums.convertTo(failure.getFailureType(), AttemptFailureType.class))
.externalMessage(failure.getExternalMessage())
.internalMessage(failure.getInternalMessage())
.stacktrace(failure.getStacktrace())
.timestamp(failure.getTimestamp())
.retryable(failure.getRetryable()))
Expand Down
12 changes: 10 additions & 2 deletions airbyte-webapp/src/components/JobItem/JobItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { JobsWithJobs } from "pages/ConnectionPage/pages/ConnectionItemPage/comp
import { AttemptRead, JobStatus } from "../../core/request/AirbyteClient";
import { useAttemptLink } from "./attemptLinkUtils";
import ContentWrapper from "./components/ContentWrapper";
import ErrorDetails from "./components/ErrorDetails";
import JobLogs from "./components/JobLogs";
import MainInfo from "./components/MainInfo";

Expand Down Expand Up @@ -53,8 +54,10 @@ export const getJobId = (job: SynchronousJobReadWithStatus | JobsWithJobs) =>
export const JobItem: React.FC<JobItemProps> = ({ shortInfo, job }) => {
const { jobId: linkedJobId } = useAttemptLink();
const [isOpen, setIsOpen] = useState(linkedJobId === getJobId(job));
const onExpand = () => setIsOpen(!isOpen);
const scrollAnchor = useRef<HTMLDivElement>(null);
const onExpand = () => {
setIsOpen(!isOpen);
};

const didSucceed = didJobSucceed(job);

Expand Down Expand Up @@ -86,7 +89,12 @@ export const JobItem: React.FC<JobItemProps> = ({ shortInfo, job }) => {
</LoadLogs>
}
>
{isOpen && <JobLogs job={job} jobIsFailed={!didSucceed} />}
{isOpen && (
<>
<ErrorDetails attempts={getJobAttemps(job)} />
<JobLogs job={job} jobIsFailed={!didSucceed} />
</>
)}
</Suspense>
</div>
</ContentWrapper>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ const AttemptDetails: React.FC<IProps> = ({ attempt, className, configType }) =>
})}: ${failureOrigin}`;
};

const getFailureMessage = (attempt: AttemptRead) => {
const getExternalFailureMessage = (attempt: AttemptRead) => {
const failure = getFailureFromAttempt(attempt);
const failureMessage = failure?.externalMessage ?? formatMessage({ id: "errorView.unknown" });

Expand Down Expand Up @@ -114,7 +114,7 @@ const AttemptDetails: React.FC<IProps> = ({ attempt, className, configType }) =>
},
{
key: getFailureOrigin(attempt),
value: getFailureMessage(attempt),
value: getExternalFailureMessage(attempt),
}
)}
</FailureReasonDetails>
Expand Down
61 changes: 61 additions & 0 deletions airbyte-webapp/src/components/JobItem/components/ErrorDetails.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import dayjs from "dayjs";
import { useIntl } from "react-intl";
import styled from "styled-components";

import { AttemptRead } from "core/request/AirbyteClient";

type IProps = {
attempts?: AttemptRead[];
};

const ExpandedFailureContainer = styled.div`
font-size: 12px;
line-height: 15px;
padding: 10px;
padding-left: 40px;
color: ${({ theme }) => theme.greyColor40};
`;

const FailureDateDisplay = styled.span`
font-style: italic;
`;

const getFailureFromAttempt = (attempt: AttemptRead) => {
return attempt.failureSummary?.failures[0];
};

const ErrorDetails: React.FC<IProps> = ({ attempts }) => {
const { formatMessage } = useIntl();

if (!attempts?.length) {
return null;
}

const getInternalFailureMessage = (attempt: AttemptRead) => {
const failure = getFailureFromAttempt(attempt);
const failureMessage = failure?.internalMessage ?? formatMessage({ id: "errorView.unknown" });

return `${formatMessage({
id: "sources.additionalFailureInfo",
})}: ${failureMessage}`;
};

const attempt = attempts[attempts.length - 1];
const failure = getFailureFromAttempt(attempt);

if (!failure) {
return null;
}

const internalMessage = getInternalFailureMessage(attempt);
return (
<ExpandedFailureContainer>
{!!failure.timestamp && (
<FailureDateDisplay>{dayjs.utc(failure.timestamp).format("YYYY-MM-DD HH:mm:ss")} - </FailureDateDisplay>
)}
{internalMessage}
</ExpandedFailureContainer>
);
};

export default ErrorDetails;
5 changes: 3 additions & 2 deletions airbyte-webapp/src/components/JobItem/components/Logs.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import React from "react";
import { FormattedMessage } from "react-intl";
import { LazyLog } from "react-lazylog";
import styled from "styled-components";
Expand Down Expand Up @@ -47,8 +46,10 @@ const Logs: React.FC<LogsProps> = ({ logsArray }) => {
lineClassName="logLine"
highlightLineClassName="highlightLogLine"
selectableLines
follow
follow={true}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, we prefer it without the ={true}

style={{ background: "transparent" }}
scrollToLine={undefined}
highlight={[]}
Comment on lines +51 to +52
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this a hack to prevent it from scrolling to a specific line?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yep - and it was undocumented and super hard to find. That's why I left this in so we would remember this for the future when we get to #12128

/>
) : (
<FormattedMessage id="sources.emptyLogs" />
Expand Down
1 change: 1 addition & 0 deletions airbyte-webapp/src/core/request/AirbyteClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -520,6 +520,7 @@ export interface AttemptFailureReason {
failureOrigin?: AttemptFailureOrigin;
failureType?: AttemptFailureType;
externalMessage?: string;
internalMessage?: string;
stacktrace?: string;
/** True if it is known that retrying may succeed, e.g. for a transient failure. False if it is known that a retry will not succeed, e.g. for a configuration issue. If not set, retryable status is not well known. */
retryable?: boolean;
Expand Down
12 changes: 12 additions & 0 deletions airbyte-webapp/src/globals.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// This file should contain all stateful modification that need to be made to libraries.
// In general this is a bad pattern that should try to be avoided, but some libraries will
// require plugins to be registered to their global instance. This file encapsulates all those
// stateful modifications.

import dayjs from "dayjs";
import customParseFormat from "dayjs/plugin/customParseFormat";
import utc from "dayjs/plugin/utc";

// Configure dayjs instance
dayjs.extend(customParseFormat);
dayjs.extend(utc);
2 changes: 2 additions & 0 deletions airbyte-webapp/src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import { lazy, Suspense } from "react";
import ReactDOM from "react-dom";
import "react-reflex/styles.css";

import "./globals";

// We do not follow default config approach since we want to init sentry asap
Sentry.init({
dsn: process.env.REACT_APP_SENTRY_DSN || window.REACT_APP_SENTRY_DSN,
Expand Down
1 change: 1 addition & 0 deletions airbyte-webapp/src/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,7 @@
"sources.copied": "Copied",
"sources.failureOrigin": "Failure Origin",
"sources.message": "Message",
"sources.additionalFailureInfo": "Additional Failure Information",
"sources.lastAttempt": "Last attempt:",

"destination.destinationSettings": "Destination Settings",
Expand Down
29 changes: 29 additions & 0 deletions docs/reference/api/generated-api-html/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -1079,11 +1079,13 @@ <h3 class="field-label">Example data</h3>
"failures" : [ {
"retryable" : true,
"stacktrace" : "stacktrace",
"internalMessage" : "internalMessage",
"externalMessage" : "externalMessage",
"timestamp" : 1
}, {
"retryable" : true,
"stacktrace" : "stacktrace",
"internalMessage" : "internalMessage",
"externalMessage" : "externalMessage",
"timestamp" : 1
} ],
Expand Down Expand Up @@ -1128,11 +1130,13 @@ <h3 class="field-label">Example data</h3>
"failures" : [ {
"retryable" : true,
"stacktrace" : "stacktrace",
"internalMessage" : "internalMessage",
"externalMessage" : "externalMessage",
"timestamp" : 1
}, {
"retryable" : true,
"stacktrace" : "stacktrace",
"internalMessage" : "internalMessage",
"externalMessage" : "externalMessage",
"timestamp" : 1
} ],
Expand Down Expand Up @@ -1400,11 +1404,13 @@ <h3 class="field-label">Example data</h3>
"failures" : [ {
"retryable" : true,
"stacktrace" : "stacktrace",
"internalMessage" : "internalMessage",
"externalMessage" : "externalMessage",
"timestamp" : 1
}, {
"retryable" : true,
"stacktrace" : "stacktrace",
"internalMessage" : "internalMessage",
"externalMessage" : "externalMessage",
"timestamp" : 1
} ],
Expand Down Expand Up @@ -1449,11 +1455,13 @@ <h3 class="field-label">Example data</h3>
"failures" : [ {
"retryable" : true,
"stacktrace" : "stacktrace",
"internalMessage" : "internalMessage",
"externalMessage" : "externalMessage",
"timestamp" : 1
}, {
"retryable" : true,
"stacktrace" : "stacktrace",
"internalMessage" : "internalMessage",
"externalMessage" : "externalMessage",
"timestamp" : 1
} ],
Expand Down Expand Up @@ -3972,11 +3980,13 @@ <h3 class="field-label">Example data</h3>
"failures" : [ {
"retryable" : true,
"stacktrace" : "stacktrace",
"internalMessage" : "internalMessage",
"externalMessage" : "externalMessage",
"timestamp" : 1
}, {
"retryable" : true,
"stacktrace" : "stacktrace",
"internalMessage" : "internalMessage",
"externalMessage" : "externalMessage",
"timestamp" : 1
} ],
Expand Down Expand Up @@ -4021,11 +4031,13 @@ <h3 class="field-label">Example data</h3>
"failures" : [ {
"retryable" : true,
"stacktrace" : "stacktrace",
"internalMessage" : "internalMessage",
"externalMessage" : "externalMessage",
"timestamp" : 1
}, {
"retryable" : true,
"stacktrace" : "stacktrace",
"internalMessage" : "internalMessage",
"externalMessage" : "externalMessage",
"timestamp" : 1
} ],
Expand Down Expand Up @@ -4197,11 +4209,13 @@ <h3 class="field-label">Example data</h3>
"failures" : [ {
"retryable" : true,
"stacktrace" : "stacktrace",
"internalMessage" : "internalMessage",
"externalMessage" : "externalMessage",
"timestamp" : 1
}, {
"retryable" : true,
"stacktrace" : "stacktrace",
"internalMessage" : "internalMessage",
"externalMessage" : "externalMessage",
"timestamp" : 1
} ],
Expand Down Expand Up @@ -4246,11 +4260,13 @@ <h3 class="field-label">Example data</h3>
"failures" : [ {
"retryable" : true,
"stacktrace" : "stacktrace",
"internalMessage" : "internalMessage",
"externalMessage" : "externalMessage",
"timestamp" : 1
}, {
"retryable" : true,
"stacktrace" : "stacktrace",
"internalMessage" : "internalMessage",
"externalMessage" : "externalMessage",
"timestamp" : 1
} ],
Expand Down Expand Up @@ -4359,11 +4375,13 @@ <h3 class="field-label">Example data</h3>
"failures" : [ {
"retryable" : true,
"stacktrace" : "stacktrace",
"internalMessage" : "internalMessage",
"externalMessage" : "externalMessage",
"timestamp" : 1
}, {
"retryable" : true,
"stacktrace" : "stacktrace",
"internalMessage" : "internalMessage",
"externalMessage" : "externalMessage",
"timestamp" : 1
} ],
Expand Down Expand Up @@ -4408,11 +4426,13 @@ <h3 class="field-label">Example data</h3>
"failures" : [ {
"retryable" : true,
"stacktrace" : "stacktrace",
"internalMessage" : "internalMessage",
"externalMessage" : "externalMessage",
"timestamp" : 1
}, {
"retryable" : true,
"stacktrace" : "stacktrace",
"internalMessage" : "internalMessage",
"externalMessage" : "externalMessage",
"timestamp" : 1
} ],
Expand Down Expand Up @@ -4521,11 +4541,13 @@ <h3 class="field-label">Example data</h3>
"failures" : [ {
"retryable" : true,
"stacktrace" : "stacktrace",
"internalMessage" : "internalMessage",
"externalMessage" : "externalMessage",
"timestamp" : 1
}, {
"retryable" : true,
"stacktrace" : "stacktrace",
"internalMessage" : "internalMessage",
"externalMessage" : "externalMessage",
"timestamp" : 1
} ],
Expand Down Expand Up @@ -4565,11 +4587,13 @@ <h3 class="field-label">Example data</h3>
"failures" : [ {
"retryable" : true,
"stacktrace" : "stacktrace",
"internalMessage" : "internalMessage",
"externalMessage" : "externalMessage",
"timestamp" : 1
}, {
"retryable" : true,
"stacktrace" : "stacktrace",
"internalMessage" : "internalMessage",
"externalMessage" : "externalMessage",
"timestamp" : 1
} ],
Expand Down Expand Up @@ -4617,11 +4641,13 @@ <h3 class="field-label">Example data</h3>
"failures" : [ {
"retryable" : true,
"stacktrace" : "stacktrace",
"internalMessage" : "internalMessage",
"externalMessage" : "externalMessage",
"timestamp" : 1
}, {
"retryable" : true,
"stacktrace" : "stacktrace",
"internalMessage" : "internalMessage",
"externalMessage" : "externalMessage",
"timestamp" : 1
} ],
Expand Down Expand Up @@ -4661,11 +4687,13 @@ <h3 class="field-label">Example data</h3>
"failures" : [ {
"retryable" : true,
"stacktrace" : "stacktrace",
"internalMessage" : "internalMessage",
"externalMessage" : "externalMessage",
"timestamp" : 1
}, {
"retryable" : true,
"stacktrace" : "stacktrace",
"internalMessage" : "internalMessage",
"externalMessage" : "externalMessage",
"timestamp" : 1
} ],
Expand Down Expand Up @@ -9957,6 +9985,7 @@ <h3><a name="AttemptFailureReason"><code>AttemptFailureReason</code> - </a> <a c
<div class="param">failureOrigin (optional)</div><div class="param-desc"><span class="param-type"><a href="#AttemptFailureOrigin">AttemptFailureOrigin</a></span> </div>
<div class="param">failureType (optional)</div><div class="param-desc"><span class="param-type"><a href="#AttemptFailureType">AttemptFailureType</a></span> </div>
<div class="param">externalMessage (optional)</div><div class="param-desc"><span class="param-type"><a href="#string">String</a></span> </div>
<div class="param">internalMessage (optional)</div><div class="param-desc"><span class="param-type"><a href="#string">String</a></span> </div>
<div class="param">stacktrace (optional)</div><div class="param-desc"><span class="param-type"><a href="#string">String</a></span> </div>
<div class="param">retryable (optional)</div><div class="param-desc"><span class="param-type"><a href="#boolean">Boolean</a></span> True if it is known that retrying may succeed, e.g. for a transient failure. False if it is known that a retry will not succeed, e.g. for a configuration issue. If not set, retryable status is not well known. </div>
<div class="param">timestamp </div><div class="param-desc"><span class="param-type"><a href="#long">Long</a></span> format: int64</div>
Expand Down