Skip to content

Commit 446f5b3

Browse files
committed
improvement: consolidate all exceptions to a json file
1 parent d0736ea commit 446f5b3

File tree

19 files changed

+355
-136
lines changed

19 files changed

+355
-136
lines changed

exceptions.json

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
{
2+
"E_CANNOT_LOOKUP_ROUTE": {
3+
"message": "Cannot find route for \"{identifier}\" identifier",
4+
"code": "E_CANNOT_FIND_ROUTE",
5+
"status": 500,
6+
"help": [
7+
"When making URL for a route. You can use one of the following identifiers",
8+
"- The route name. Defined using `Route.as()`",
9+
"- The route controller.method name. `PostsController.show`"
10+
]
11+
},
12+
"E_CANNOT_SERIALIZE_RESPONSE_BODY": {
13+
"message": "Unable to send HTTP response. Cannot serialize \"{dataType}\" to a string",
14+
"code": "E_CANNOT_SERIALIZE_RESPONSE_BODY",
15+
"status": 500,
16+
"help": [
17+
"AdonisJS can only send following data types as a response",
18+
"- object, array, number, boolean, date, buffer and string",
19+
"- For sending streams, you must use `response.stream` method",
20+
"- For downloading files, you must use `response.download` method"
21+
]
22+
},
23+
"E_HTTP_EXCEPTION": {
24+
"message": "Request aborted with status code {status}",
25+
"code": "E_HTTP_EXCEPTION",
26+
"help": ["A generic exception usually raised using \"response.abort\""]
27+
},
28+
"E_CANNOT_DEFINE_GROUP_NAME": {
29+
"message": "All the routes inside a group must have names before calling \"Route.group.as\"",
30+
"code": "E_CANNOT_DEFINE_GROUP_NAME",
31+
"status": 500,
32+
"help": [
33+
"`Route.group.as` adds a prefix to the route names and hence it cannot prefix a route with no initial name",
34+
"To fix the issue, you must give name to all the routes inside a group"
35+
]
36+
},
37+
"E_DUPLICATE_ROUTE_NAME": {
38+
"message": "Duplicate route name \"{name}\"",
39+
"code": "E_DUPLICATE_ROUTE_NAME",
40+
"status": 500,
41+
"help": [
42+
"Names are assigned to the routes to identify them uniquely and hence a duplicate name is not allowed",
43+
"Run `node ace list:routes` to find the route using this name"
44+
]
45+
},
46+
"E_DUPLICATE_ROUTE": {
47+
"message": "Duplicate route \"{method}:{pattern}\"",
48+
"code": "E_DUPLICATE_ROUTE",
49+
"status": 500,
50+
"help": [
51+
"The route with the pattern is already registered",
52+
"Double check your routes file or run `node ace list:routes`"
53+
]
54+
},
55+
"E_DUPLICATE_ROUTE_PARAM": {
56+
"message": "The \"{param}\" param is mentioned twice in the route pattern \"{pattern}\"",
57+
"code": "E_DUPLICATE_ROUTE_PARAM",
58+
"status": 500
59+
},
60+
"E_ROUTE_NOT_FOUND": {
61+
"message": "Cannot {method}:{url}",
62+
"code": "E_ROUTE_NOT_FOUND",
63+
"status": 404
64+
},
65+
"E_MISSING_NAMED_MIDDLEWARE": {
66+
"message": "Cannot find a middleware named \"{name}\"",
67+
"code": "E_MISSING_NAMED_MIDDLEWARE",
68+
"status": 500,
69+
"help": [
70+
"The named middleware are supposed to be registered inside `start/kernel` file first",
71+
"Open the file and make sure middleware is defined inside `Server.middleware.registerNamed()` call"
72+
]
73+
},
74+
"E_CANNOT_MAKE_ROUTE_URL": {
75+
"message": "\"{param}\" param is required to make URL for \"{pattern}\" route",
76+
"code": "E_CANNOT_MAKE_ROUTE_URL",
77+
"status": 500,
78+
"help": [
79+
"Make sure to define params object when using `Route.makeUrl` or the view help `route`."
80+
]
81+
}
82+
}

npm-audit.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ <h5 class="card-title">
5555
<div class="card">
5656
<div class="card-body">
5757
<h5 class="card-title">
58-
July 23rd 2020, 7:24:11 am
58+
July 24th 2020, 6:20:27 am
5959
</h5>
6060
<p class="card-text">Last updated</p>
6161
</div>

package-lock.json

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

package.json

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,10 @@
44
"description": "AdonisJS HTTP server with support packed with Routing and Cookies",
55
"main": "build/providers/HttpServerProvider.js",
66
"files": [
7-
"build/src",
8-
"build/providers",
97
"build/adonis-typings",
8+
"build/providers",
9+
"build/src",
10+
"build/exceptions.json",
1011
"build/standalone.d.ts",
1112
"build/standalone.js"
1213
],
@@ -44,7 +45,7 @@
4445
"@poppinss/dev-utils": "^1.0.8",
4546
"@types/cookie": "^0.4.0",
4647
"@types/ms": "^0.7.31",
47-
"@types/node": "^14.0.24",
48+
"@types/node": "^14.0.25",
4849
"@types/pluralize": "0.0.29",
4950
"@types/proxy-addr": "^2.0.0",
5051
"@types/qs": "^6.9.3",
@@ -102,7 +103,7 @@
102103
"anyBranch": false
103104
},
104105
"dependencies": {
105-
"@poppinss/utils": "^2.3.0",
106+
"@poppinss/utils": "^2.4.1",
106107
"accepts": "^1.3.7",
107108
"co-compose": "^6.0.1",
108109
"content-disposition": "^0.5.3",
@@ -136,5 +137,8 @@
136137
"bugs": {
137138
"url": "https://github.com/adonisjs/http-server/issues"
138139
},
139-
"homepage": "https://github.com/adonisjs/http-server#readme"
140+
"homepage": "https://github.com/adonisjs/http-server#readme",
141+
"adonisjs": {
142+
"exceptions": "./build/exceptions.json"
143+
}
140144
}

src/Exceptions/HttpException.ts

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
/**
2+
* @adonisjs/http-server
3+
*
4+
* (c) Harminder Virk <[email protected]>
5+
*
6+
* For the full copyright and license information, please view the LICENSE
7+
* file that was distributed with this source code.
8+
*/
9+
10+
/// <reference path="../../adonis-typings/index.ts" />
11+
12+
import { Exception, interpolate } from '@poppinss/utils'
13+
import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'
14+
15+
import { E_HTTP_EXCEPTION } from '../../exceptions.json'
16+
17+
/**
18+
* Custom exception to abort requests as one liners
19+
*/
20+
export class HttpException extends Exception {
21+
public body: any
22+
23+
/**
24+
* This method returns an instance of the exception class
25+
*/
26+
public static invoke(body: any, status: number, code?: string) {
27+
const message = E_HTTP_EXCEPTION.message
28+
code = code || E_HTTP_EXCEPTION.code
29+
30+
if (body !== null && typeof body === 'object') {
31+
const error = new this(body.message || interpolate(message, { status }), status, code)
32+
error.body = body
33+
return error
34+
}
35+
36+
const error = new this(body || interpolate(message, { status }), status, code)
37+
error.body = error.message
38+
return error
39+
}
40+
41+
/**
42+
* Handle itself by making the response. This only works when using the
43+
* base exception handler shipped by AdonisJs
44+
*/
45+
public handle(error: HttpException, ctx: HttpContextContract) {
46+
ctx.response.status(error.status).send(error.body)
47+
}
48+
}

src/Exceptions/RouterException.ts

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
/*
2+
* @adonisjs/http-server
3+
*
4+
* (c) Harminder Virk <[email protected]>
5+
*
6+
* For the full copyright and license information, please view the LICENSE
7+
* file that was distributed with this source code.
8+
*/
9+
10+
import { Exception, interpolate } from '@poppinss/utils'
11+
import {
12+
E_DUPLICATE_ROUTE,
13+
E_CANNOT_LOOKUP_ROUTE,
14+
E_DUPLICATE_ROUTE_NAME,
15+
E_CANNOT_MAKE_ROUTE_URL,
16+
E_DUPLICATE_ROUTE_PARAM,
17+
E_CANNOT_DEFINE_GROUP_NAME,
18+
} from '../../exceptions.json'
19+
20+
/**
21+
* Exceptions related to the HTTP router
22+
*/
23+
export class RouterException extends Exception {
24+
/**
25+
* Raised when one of the routes inside the group doesn't have a name
26+
* but an attempt is made to name the group
27+
*/
28+
public static cannotDefineGroupName() {
29+
const error = new this(
30+
E_CANNOT_DEFINE_GROUP_NAME.message,
31+
E_CANNOT_DEFINE_GROUP_NAME.status,
32+
E_CANNOT_DEFINE_GROUP_NAME.code
33+
)
34+
35+
error.help = E_CANNOT_DEFINE_GROUP_NAME.help.join('\n')
36+
throw error
37+
}
38+
39+
/**
40+
* Raised when a duplicate route pattern is find for the same HTTP method
41+
*/
42+
public static duplicateRoute(method: string, pattern: string) {
43+
const error = new this(
44+
interpolate(E_DUPLICATE_ROUTE.message, { method, pattern }),
45+
E_DUPLICATE_ROUTE.status,
46+
E_DUPLICATE_ROUTE.code
47+
)
48+
49+
error.help = E_DUPLICATE_ROUTE.help.join('\n')
50+
throw error
51+
}
52+
53+
/**
54+
* Raised when a route has duplicate params
55+
*/
56+
public static duplicateRouteParam(param: string, pattern: string) {
57+
return new this(
58+
interpolate(E_DUPLICATE_ROUTE_PARAM.message, { param, pattern }),
59+
E_DUPLICATE_ROUTE_PARAM.status,
60+
E_DUPLICATE_ROUTE_PARAM.code
61+
)
62+
}
63+
64+
/**
65+
* Raised when route name is not unique
66+
*/
67+
public static duplicateRouteName(name: string) {
68+
const error = new this(
69+
interpolate(E_DUPLICATE_ROUTE_NAME.message, { name }),
70+
E_DUPLICATE_ROUTE_NAME.status,
71+
E_DUPLICATE_ROUTE_NAME.code
72+
)
73+
74+
error.help = E_DUPLICATE_ROUTE_NAME.help.join('\n')
75+
throw error
76+
}
77+
78+
/**
79+
* Raised when unable to make url for a given route, because one of the
80+
* params value is not defined
81+
*/
82+
public static cannotMakeRoute(param: string, pattern: string) {
83+
const error = new this(
84+
interpolate(E_CANNOT_MAKE_ROUTE_URL.message, { pattern, param }),
85+
E_CANNOT_MAKE_ROUTE_URL.status,
86+
E_CANNOT_MAKE_ROUTE_URL.code
87+
)
88+
89+
error.help = E_CANNOT_MAKE_ROUTE_URL.help.join('\n')
90+
throw error
91+
}
92+
93+
/**
94+
* Raised when unable to lookup a route using its identifier
95+
*/
96+
public static cannotLookupRoute(identifier: string) {
97+
const error = new this(
98+
interpolate(E_CANNOT_LOOKUP_ROUTE.message, { identifier }),
99+
E_CANNOT_LOOKUP_ROUTE.status,
100+
E_CANNOT_LOOKUP_ROUTE.code
101+
)
102+
103+
error.help = E_CANNOT_LOOKUP_ROUTE.help.join('\n')
104+
throw error
105+
}
106+
}

src/Redirect/index.ts

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,10 @@ import { parse } from 'url'
1313
import { stringify } from 'qs'
1414
import encodeurl from 'encodeurl'
1515
import { IncomingMessage } from 'http'
16-
17-
import { RedirectContract, ResponseContract } from '@ioc:Adonis/Core/Response'
1816
import { RouterContract, MakeUrlOptions } from '@ioc:Adonis/Core/Route'
17+
import { RedirectContract, ResponseContract } from '@ioc:Adonis/Core/Response'
18+
19+
import { RouterException } from '../Exceptions/RouterException'
1920

2021
/**
2122
* Exposes the API to construct redirect routes
@@ -88,11 +89,9 @@ export class Redirect implements RedirectContract {
8889
* Redirect the request using a route identifier.
8990
*/
9091
public toRoute(routeIdentifier: string, urlOptions?: MakeUrlOptions, domain?: string) {
91-
// const route = this.router.lookup(routeIdentifier, domain)
92-
9392
const url = this.router.makeUrl(routeIdentifier, urlOptions, domain)
9493
if (!url) {
95-
throw new Error(`Unable to lookup route for "${routeIdentifier}" identifier`)
94+
throw RouterException.cannotLookupRoute(routeIdentifier)
9695
}
9796

9897
return this.toPath(url)

0 commit comments

Comments
 (0)