Skip to content

Commit

Permalink
Add throwOnError and errorMessage properties to improve error handling
Browse files Browse the repository at this point in the history
  • Loading branch information
grubersjoe committed Jan 18, 2024
1 parent e838636 commit 066eb3c
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 25 deletions.
48 changes: 38 additions & 10 deletions example/src/components/Docs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -77,10 +77,10 @@ const Docs: FunctionComponent = () => {
</h4>

<ErrorBoundary fallbackRender={errorRenderer} key={username}>
<GitHubCalendar username={username} fontSize={16} />
<GitHubCalendar username={username} fontSize={16} throwOnError />
</ErrorBoundary>

<p style={{ marginBottom: '1.25rem' }}>
<p style={{ marginTop: '1.25rem', marginBottom: '1.25rem' }}>
Made with love by <a href="https://jogruber.de">@grubersjoe</a>,
current version:{' '}
<a href="https://www.npmjs.com/package/react-github-calendar">
Expand Down Expand Up @@ -117,11 +117,15 @@ const Docs: FunctionComponent = () => {
<section>
<h2>Component properties</h2>
<p>
See{' '}
The component uses{' '}
<a href="https://github.com/grubersjoe/react-activity-calendar">
<code>react-activity-calendar</code>
</a>{' '}
internally, so all its properties are supported. See the{' '}
<a href="https://grubersjoe.github.io/react-activity-calendar/?path=/docs/react-activity-calendar--docs">
documentation
</a>{' '}
of <code>react-activity-calendar</code>
</a>
.
</p>
<div className="table-overflow">
<table>
Expand All @@ -136,7 +140,7 @@ const Docs: FunctionComponent = () => {
<tbody>
<tr>
<td>username</td>
<td>string</td>
<td>string!</td>
<td />
<td>
A GitHub username (<em>required, obviously</em>).
Expand Down Expand Up @@ -177,6 +181,16 @@ const Docs: FunctionComponent = () => {
Use a specific color scheme instead of the system one.
</td>
</tr>
<tr>
<td>errorMessage</td>
<td>string</td>
<td />
<td>
Message to show if fetching GitHub contribution data fails.
Only relevant if <code>throwOnError</code> is{' '}
<code>false</code>.
</td>
</tr>
<tr>
<td>eventHandlers</td>
<td>
Expand Down Expand Up @@ -233,7 +247,7 @@ const Docs: FunctionComponent = () => {
<td />
<td>
Localization strings for all calendar labels.{' '}
<a href="https://grubersjoe.github.io/react-activity-calendar/?path=/story/react-activity-calendar--with-localized-labels">
<a href="https://grubersjoe.github.io/react-activity-calendar/?path=/story/react-activity-calendar--localized-labels">
See here for details
</a>
.
Expand Down Expand Up @@ -309,12 +323,25 @@ const Docs: FunctionComponent = () => {
any valid CSS format.
</p>
<p>
<a href="https://grubersjoe.github.io/react-activity-calendar/?path=/story/react-activity-calendar--with-theme">
<a href="https://grubersjoe.github.io/react-activity-calendar/?path=/story/react-activity-calendar--color-themes">
See this example
</a>
</p>
</td>
</tr>
<tr>
<td>throwOnError</td>
<td>boolean</td>
<td>false</td>
<td>
Whether to throw an <code>Error</code> if fetching GitHub
contribution data fails. Use a React{' '}
<a href="https://react.dev/reference/react/Component#catching-rendering-errors-with-an-error-boundary">
error boundary
</a>{' '}
to handle the error.
</td>
</tr>
<tr>
<td>totalCount</td>
<td>number</td>
Expand Down Expand Up @@ -384,7 +411,7 @@ const Docs: FunctionComponent = () => {
<h3 id="tooltips">How do I add tooltips?</h3>
<p>
See{' '}
<a href="https://grubersjoe.github.io/react-activity-calendar/?path=/story/react-activity-calendar--with-tooltips">
<a href="https://grubersjoe.github.io/react-activity-calendar/?path=/story/react-activity-calendar--tooltips">
tooltip examples
</a>{' '}
how to use the <code>renderBlock</code> prop. .
Expand Down Expand Up @@ -450,10 +477,11 @@ function transformData(data: Array<Activity>): Array<Activity>;`}
labels={{
totalCount: '{{count}} contributions in the last half year',
}}
throwOnError
/>
</ErrorBoundary>

<p>
<p style={{ marginTop: '1.25rem' }}>
The total count will be recalculated based on the transformed data.
However, you can enforce that the total count of the untransformed
data is shown by setting the <code>transformTotalCount</code> to{' '}
Expand Down
4 changes: 0 additions & 4 deletions example/src/styles.scss
Original file line number Diff line number Diff line change
Expand Up @@ -303,10 +303,6 @@ button {
font-size: 90%;
}

.react-activity-calendar {
margin: 0 0 1.5rem;
}

.github-corner .octo {
fill: var(--color-text);
}
Expand Down
2 changes: 2 additions & 0 deletions src/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ export interface Props extends Omit<ActivityCalendarProps, 'data'> {
year?: number | 'last';
transformData?: (data: Array<Activity>) => Array<Activity>;
transformTotalCount?: boolean;
throwOnError?: boolean;
errorMessage?: string;
}

declare const GitHubCalendar: FunctionComponent<Props>;
Expand Down
28 changes: 17 additions & 11 deletions src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ export interface Props extends Omit<CalendarProps, 'data'> {
year?: Year;
transformData?: (data: Array<Activity>) => Array<Activity>;
transformTotalCount?: boolean;
throwOnError?: boolean;
errorMessage?: string;
}

async function fetchCalendarData(
Expand All @@ -27,7 +29,7 @@ async function fetchCalendarData(

if (!response.ok) {
throw Error(
`Fetching contribution data for '${username}' failed: ${(data as ApiErrorResponse).error}`,
`Fetching GitHub contribution data for "${username}" failed: ${(data as ApiErrorResponse).error}`,
);
}

Expand All @@ -37,28 +39,34 @@ const GitHubCalendar = ({
username,
year = 'last',
labels,
transformData: transformDataCallback,
transformData: transformFn,
transformTotalCount = true,
throwOnError = false,
errorMessage = `Error – Fetching GitHub contribution data for "${username}" failed.`,
...props
}: Props) => {
const [data, setData] = useState<ApiResponse | null>(null);
const [loading, setLoading] = useState(false);
const [error, setError] = useState<Error | null>(null);
const [fetchError, setFetchError] = useState<Error | null>(null);

const fetchData = useCallback(() => {
setLoading(true);
setError(null);
setFetchError(null);
fetchCalendarData(username, year)
.then(setData)
.catch(setError)
.catch(setFetchError)
.finally(() => setLoading(false));
}, [username, year]);

useEffect(fetchData, [fetchData]);

// React error boundaries can't handle asynchronous code, so rethrow.
if (error) {
throw error;
if (fetchError) {
if (throwOnError) {
throw fetchError;
} else {
return <div>{errorMessage}</div>;
}
}

if (loading || !data) {
Expand All @@ -78,12 +86,10 @@ const GitHubCalendar = ({

return (
<Calendar
data={transformData(data.contributions, transformDataCallback)}
data={transformData(data.contributions, transformFn)}
theme={theme}
labels={Object.assign({}, defaultLabels, labels)}
totalCount={
transformDataCallback && transformTotalCount ? undefined : totalCount
}
totalCount={transformFn && transformTotalCount ? undefined : totalCount}
{...props}
maxLevel={4}
/>
Expand Down

0 comments on commit 066eb3c

Please sign in to comment.