Skip to content

Commit c86e29a

Browse files
authored
Add error handling (#27)
* Fix application
1 parent defcbef commit c86e29a

File tree

14 files changed

+1042
-1077
lines changed

14 files changed

+1042
-1077
lines changed

library/src/config/config.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
export interface ConfigInterface {
2-
show: ShowConfig,
3-
disableDefaultTheme: boolean,
2+
show: ShowConfig;
3+
disableDefaultTheme: boolean;
4+
showErrors: boolean;
45
}
56

67
interface ShowConfig {
@@ -13,4 +14,3 @@ interface ShowConfig {
1314
messages: boolean;
1415
schemas: boolean;
1516
}
16-

library/src/config/default.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,6 @@ export const defaultConfig: ConfigInterface = {
1111
messages: true,
1212
schemas: true,
1313
},
14+
showErrors: false,
1415
disableDefaultTheme: false,
15-
}
16+
};

library/src/containers/AsyncApi/AsyncApi.tsx

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import Security from '../Security/Security';
1111
import TopicsComponent from '../Topics/Topics';
1212
import MessagesComponent from '../Messages/Messages';
1313
import SchemasComponent from '../Schemas/Schemas';
14+
import ErrorComponent from '../Error/Error';
1415

1516
import { AsyncApiWrapper } from './styled';
1617

@@ -23,6 +24,7 @@ export interface AsyncApiProps {
2324
interface AsyncApiState {
2425
validatedSchema: AsyncApi;
2526
validated: boolean;
27+
error?: Error | Error[];
2628
}
2729

2830
const defaultAsyncApi: AsyncApi = {
@@ -37,19 +39,26 @@ class AsyncApiComponent extends Component<AsyncApiProps, AsyncApiState> {
3739
state = {
3840
validatedSchema: defaultAsyncApi,
3941
validated: false,
42+
error: undefined,
4043
};
4144

45+
private async prepareSchema(schema: string | Object) {
46+
try {
47+
let validatedSchema = await this.validateSchema(schema);
48+
validatedSchema = this.beautifySchema(validatedSchema);
49+
this.setState({ validatedSchema, validated: true, error: undefined });
50+
} catch (e) {
51+
this.setState({ error: e });
52+
}
53+
}
54+
4255
async componentWillMount() {
43-
let validatedSchema = await this.validateSchema(this.props.schema);
44-
validatedSchema = this.beautifySchema(validatedSchema);
45-
this.setState({ validatedSchema, validated: true });
56+
this.prepareSchema(this.props.schema);
4657
}
4758

4859
async componentWillReceiveProps(nextProps: AsyncApiProps) {
4960
if (nextProps.schema !== this.props.schema) {
50-
let validatedSchema = await this.validateSchema(nextProps.schema);
51-
validatedSchema = this.beautifySchema(validatedSchema);
52-
this.setState({ validatedSchema });
61+
this.prepareSchema(nextProps.schema);
5362
}
5463
}
5564

@@ -73,8 +82,7 @@ class AsyncApiComponent extends Component<AsyncApiProps, AsyncApiState> {
7382

7483
render() {
7584
const { theme, config } = this.props;
76-
const { validatedSchema, validated } = this.state;
77-
85+
const { validatedSchema, validated, error } = this.state;
7886
const concatenatedConfig: ConfigInterface = {
7987
...defaultConfig,
8088
...config,
@@ -83,6 +91,7 @@ class AsyncApiComponent extends Component<AsyncApiProps, AsyncApiState> {
8391
...(config && config.show ? config.show : {}),
8492
},
8593
};
94+
8695
const concatenatedTheme: ThemeInterface = concatenatedConfig.disableDefaultTheme
8796
? (theme as ThemeInterface)
8897
: { ...defaultTheme, ...theme };
@@ -92,6 +101,10 @@ class AsyncApiComponent extends Component<AsyncApiProps, AsyncApiState> {
92101
return (
93102
<ThemeProvider theme={concatenatedTheme}>
94103
<AsyncApiWrapper>
104+
{this.showComponent(
105+
concatenatedConfig.showErrors && Boolean(error),
106+
<ErrorComponent error={error} />,
107+
)}
95108
{this.showComponent(
96109
concatenatedConfig.show.info && Boolean(validatedSchema.info),
97110
<InfoComponent
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import React, { Component } from 'react';
2+
import {
3+
ErrorWrapper,
4+
ErrorHeader,
5+
ErrorContent,
6+
ErrorCode,
7+
ErrorPre,
8+
} from './styled';
9+
10+
interface Props {
11+
error?: Error | Error[];
12+
}
13+
14+
class ErrorComponent extends Component<Props> {
15+
private renderErrors(error: Error | Error[]): React.ReactNode {
16+
if (Array.isArray(error)) {
17+
return error.map((singleError: Error, index: number) => (
18+
<ErrorCode key={index}>
19+
{(singleError && singleError.message) || singleError}
20+
</ErrorCode>
21+
));
22+
}
23+
24+
return <ErrorCode>{(error && error.message) || error}</ErrorCode>;
25+
}
26+
27+
render() {
28+
const { error } = this.props;
29+
30+
if (!error) return null;
31+
32+
return (
33+
<ErrorWrapper>
34+
<ErrorHeader>There are errors in your document:</ErrorHeader>
35+
<ErrorContent>
36+
<ErrorPre>{this.renderErrors(error)}</ErrorPre>
37+
</ErrorContent>
38+
</ErrorWrapper>
39+
);
40+
}
41+
}
42+
43+
export default ErrorComponent;
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import styled from 'styled-components';
2+
3+
export const ErrorWrapper = styled.div`
4+
${props => props.theme.errorWrapper}
5+
`;
6+
export const ErrorHeader = styled.div`
7+
${props => props.theme.errorHeader}
8+
`;
9+
export const ErrorContent = styled.div`
10+
${props => props.theme.errorContent}
11+
`;
12+
13+
export const ErrorCode = styled.code`
14+
${props => props.theme.errorCode}
15+
`;
16+
17+
export const ErrorPre = styled.pre`
18+
${props => props.theme.errorPre}
19+
`;

library/src/helpers/parser.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -29,21 +29,21 @@ class Parser {
2929
} catch (e) {
3030
return require('js-yaml').safeLoad(content);
3131
}
32-
};
33-
32+
}
33+
3434
private async dereference(json: JSON): Promise<any> {
3535
return RefParser.dereference(json, {
3636
dereference: {
37-
circular: 'ignore'
38-
}
37+
circular: 'ignore',
38+
},
3939
});
4040
}
41-
41+
4242
private async bundle(json: JSON): Promise<any> {
4343
return RefParser.bundle(json, {
4444
dereference: {
45-
circular: 'ignore'
46-
}
45+
circular: 'ignore',
46+
},
4747
});
4848
}
4949

@@ -59,7 +59,7 @@ class Parser {
5959

6060
private async validate(json: JSON, schema: string): Promise<JSON> {
6161
return new Promise<JSON>((resolve, reject) => {
62-
this.validator.validate(json, schema, (err) => {
62+
this.validator.validate(json, schema, err => {
6363
if (err) return reject(err);
6464
return resolve(json);
6565
});

0 commit comments

Comments
 (0)