Skip to content

Commit 0c08e9a

Browse files
authored
Merge pull request #26 from piyook/feat/add-mock-error-route
Feat(): add mock error route
2 parents 72b92eb + 0cfc3ae commit 0c08e9a

File tree

6 files changed

+133
-59
lines changed

6 files changed

+133
-59
lines changed

README.md

Lines changed: 34 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -86,14 +86,14 @@ npm run dev
8686

8787
The framework is written in TypeScript and can :
8888

89-
- Serve data from static files (JSON or text)
90-
- Serve media : Images and Videos
91-
- Serve markdown files
92-
- Be used to write and test AWS Lambda Functions
93-
- Use custom middleware to transform input/output
94-
- Serve random Database seed data
95-
- Serve persisted mock data to the database
96-
- Perform CRUD operations on the local database via a REST endpoint
89+
- Serve data from static files (JSON or text)
90+
- Serve media : Images and Videos
91+
- Serve markdown files
92+
- Be used to write and test AWS Lambda Functions
93+
- Use custom middleware to transform input/output
94+
- Serve random Database seed data
95+
- Serve persisted mock data to the database
96+
- Perform CRUD operations on the local database via a REST endpoint
9797

9898
### Setting up a new API route
9999

@@ -111,7 +111,7 @@ mkdir src/api/users
111111

112112
#### IMPORTANT
113113

114-
Rember to use 'npm run dev' to start a local dev server when developing new API endpoints.
114+
Remember to use 'npm run dev' to start a local dev server when developing new API endpoints.
115115

116116
Once endpoints have been developed and tested then use 'npm run start' to build the docker image and start a container to serve the endpoints on localhost (or use 'npm run rebuild' or 'npm run nuke' if changes need to be made to an existing docker image).
117117

@@ -271,6 +271,31 @@ http://localhost:8000/api/json/demo
271271

272272
The templates directory contains some templates for different type of handlers, models and seeders but the demo api endpoints can just as easily be copied and modified for individual use cases.
273273

274+
### 13. Error Route
275+
276+
It can be useful to mock api errors in order to test frontend error handling logic.
277+
278+
To do this redirect frontend fetch requests to the api/error route.
279+
280+
```
281+
http://localhost:8000/api/error
282+
```
283+
284+
The default error for this route is a '404: not found' error but if specific errors are required, then this can be customised by passing 'status' to the endpoint and also a custom 'message' if required.
285+
286+
E.g to mimic a 500 'Internal Server Error'
287+
288+
```
289+
http://localhost:8000/api/error?status=500&message=Internal%20Server%20Error
290+
```
291+
292+
this will return a 500 error code and the JSON response below:
293+
294+
```
295+
{"error":"500: Internal Server Error"}
296+
297+
```
298+
274299
## Customisation
275300

276301
### Changing api url prefix
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
describe('default mock error endpoint works as expected', () => {
2+
it('checks default error endpoint is running', () => {
3+
cy.request({ url: '/api/error', failOnStatusCode: false }).then(
4+
(response) => {
5+
expect(response.status).to.eq(404);
6+
expect(response.body).to.be.jsonSchema({
7+
error: '404: Not Found',
8+
});
9+
},
10+
);
11+
});
12+
13+
it('checks default error endpoint is running', () => {
14+
cy.request({
15+
url: '/api/error?status=500&message=Internal%20Server%20Error',
16+
failOnStatusCode: false,
17+
}).then((response) => {
18+
expect(response.status).to.eq(500);
19+
expect(response.body).to.be.jsonSchema({
20+
error: '500: Internal Server Error',
21+
});
22+
});
23+
});
24+
});

cypress/e2e/server-page-spec.cy.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ describe('Server page contains expected information', () => {
1010
'/api/posts',
1111
'/api/users',
1212
'/api/videos',
13+
'/api/error',
1314
];
1415
cy.visit('/');
1516
cy.get('h1').contains('Running');

package-lock.json

Lines changed: 41 additions & 42 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,29 +18,29 @@
1818
"validate-branch-name": "bash validate-branch-name.sh"
1919
},
2020
"dependencies": {
21-
"@faker-js/faker": "^9.6.0",
21+
"@faker-js/faker": "^9.7.0",
2222
"@mswjs/data": "^0.16.2",
2323
"@mswjs/http-middleware": "^0.10.3",
2424
"@types/chai-json-schema": "^1.4.10",
2525
"@types/express": "^5.0.1",
2626
"@types/markdown-it": "^14.1.2",
2727
"chai-json-schema": "^1.5.1",
28-
"dotenv": "^16.4.7",
28+
"dotenv": "^16.5.0",
2929
"highlight.js": "^11.11.1",
3030
"markdown-it": "^14.1.0",
31-
"msw": "^2.7.3",
31+
"msw": "^2.7.4",
3232
"tsx": "^4.19.3",
33-
"typescript": "^5.8.2",
33+
"typescript": "^5.8.3",
3434
"zod": "^3.24.2"
3535
},
3636
"devDependencies": {
3737
"@commitlint/cli": "^19.8.0",
3838
"@commitlint/config-conventional": "^19.8.0",
39-
"@types/aws-lambda": "^8.10.148",
40-
"@types/node": "^22.13.13",
41-
"cypress": "^14.2.0",
39+
"@types/aws-lambda": "^8.10.149",
40+
"@types/node": "^22.14.1",
41+
"cypress": "^14.3.0",
4242
"husky": "^9.1.7",
43-
"lint-staged": "^15.5.0",
43+
"lint-staged": "^15.5.1",
4444
"prettier": "3.5.3",
4545
"start-server-and-test": "^2.0.11",
4646
"xo": "^0.60.0"

src/api/error/api.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import fs from 'node:fs';
2+
import path from 'node:path';
3+
import { http, HttpResponse } from 'msw';
4+
5+
function handler(pathName: string) {
6+
return [
7+
http.get(`/${pathName}`, ({ request }) => {
8+
const url = new URL(request.url);
9+
10+
const statusCode = Number.parseInt(
11+
url.searchParams.get('status') ?? '404',
12+
10,
13+
);
14+
15+
const errorMessage = url.searchParams.get('message') ?? 'Not Found';
16+
17+
return HttpResponse.json(
18+
{ error: statusCode + ': ' + errorMessage },
19+
{ status: statusCode },
20+
);
21+
}),
22+
];
23+
}
24+
25+
export default handler;

0 commit comments

Comments
 (0)