Skip to content

Commit 5d31f66

Browse files
committed
feat: add make:exception command
1 parent 56e3ebc commit 5d31f66

File tree

5 files changed

+170
-2
lines changed

5 files changed

+170
-2
lines changed

commands/Make/Exception.ts

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
/*
2+
* @adonisjs/assembler
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 { join } from 'path'
11+
import { args, flags } from '@adonisjs/ace'
12+
import { RcFile } from '@ioc:Adonis/Core/Application'
13+
import { BaseGenerator } from './Base'
14+
15+
/**
16+
* Command to make a new event exceptions class
17+
*/
18+
export default class MakeException extends BaseGenerator {
19+
/**
20+
* Required by BaseGenerator
21+
*/
22+
protected $form = 'singular' as const
23+
protected $pattern = 'pascalcase' as const
24+
protected $resourceName: string
25+
protected $suffix = 'Exception'
26+
27+
/**
28+
* Command meta data
29+
*/
30+
public static commandName = 'make:exception'
31+
public static description = 'Make a new exception handle'
32+
33+
@args.string({ description: 'Name of the exception class' })
34+
public name: string
35+
36+
@flags.boolean({ description: 'Add handle method to self handle the exception' })
37+
public selfHandle: boolean
38+
39+
/**
40+
* Returns the template stub
41+
*/
42+
protected $getStub (): string {
43+
return join(
44+
__dirname,
45+
'..',
46+
'..',
47+
'templates',
48+
this.selfHandle ? 'self-handle-exception.txt' : 'exception.txt',
49+
)
50+
}
51+
52+
/**
53+
* Pull path from the `exceptions` namespace declaration from
54+
* the `.adonisrc.json` file or fallback to `app/Exceptions`
55+
*/
56+
protected $getDestinationPath (rcContents: RcFile): string {
57+
return this.$getPathForNamespace(rcContents, 'exceptions') || 'app/Exceptions'
58+
}
59+
60+
public async handle () {
61+
this.$resourceName = this.name
62+
await super.generate()
63+
}
64+
}

templates/exception.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
export default class ${filename} {
2+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'
2+
3+
export default class ${filename} {
4+
public async handle (error: this, ctx: HttpContextContract) {
5+
ctx.response.status(error.status || 500).send(error.message)
6+
}
7+
}

test/make-exception.spec.ts

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
/*
2+
* @adonisjs/assembler
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 test from 'japa'
11+
import { join } from 'path'
12+
import { Ioc } from '@adonisjs/fold'
13+
import { Kernel } from '@adonisjs/ace'
14+
import { Filesystem } from '@poppinss/dev-utils'
15+
import { Application } from '@adonisjs/application/build/standalone'
16+
17+
import { toNewlineArray } from '../test-helpers'
18+
import MakeException from '../commands/Make/Exception'
19+
20+
const fs = new Filesystem(join(__dirname, '__app'))
21+
const templates = new Filesystem(join(__dirname, '..', 'templates'))
22+
23+
test.group('Make Exception', (group) => {
24+
group.before(() => {
25+
process.env.ADONIS_ACE_CWD = fs.basePath
26+
})
27+
28+
group.after(() => {
29+
delete process.env.ADONIS_ACE_CWD
30+
})
31+
32+
group.afterEach(async () => {
33+
await fs.cleanup()
34+
})
35+
36+
test('make an exception class inside the default directory', async (assert) => {
37+
await fs.add('.adonisrc.json', JSON.stringify({}))
38+
39+
const app = new Application(fs.basePath, new Ioc(), {}, {})
40+
41+
const exception = new MakeException(app, new Kernel(app))
42+
exception.name = 'user'
43+
await exception.handle()
44+
45+
const UserException = await fs.get('app/Exceptions/UserException.ts')
46+
const ExceptionTemplate = await templates.get('exception.txt')
47+
assert.deepEqual(
48+
toNewlineArray(UserException),
49+
toNewlineArray(ExceptionTemplate.replace('${filename}', 'UserException')),
50+
)
51+
})
52+
53+
test('make a self-handled exception class inside the default directory', async (assert) => {
54+
await fs.add('.adonisrc.json', JSON.stringify({}))
55+
56+
const app = new Application(fs.basePath, new Ioc(), {}, {})
57+
58+
const exception = new MakeException(app, new Kernel(app))
59+
exception.name = 'user'
60+
exception.selfHandle = true
61+
await exception.handle()
62+
63+
const UserException = await fs.get('app/Exceptions/UserException.ts')
64+
const ExceptionTemplate = await templates.get('self-handle-exception.txt')
65+
assert.deepEqual(
66+
toNewlineArray(UserException),
67+
toNewlineArray(ExceptionTemplate.replace('${filename}', 'UserException')),
68+
)
69+
})
70+
71+
test('make an exception class inside a custom directory', async (assert) => {
72+
await fs.add('.adonisrc.json', JSON.stringify({
73+
namespaces: {
74+
exceptions: 'App/Exceptions/Custom',
75+
},
76+
aliases: {
77+
App: './app',
78+
},
79+
}))
80+
81+
const app = new Application(fs.basePath, new Ioc(), {}, {})
82+
83+
const exception = new MakeException(app, new Kernel(app))
84+
exception.name = 'user'
85+
exception.selfHandle = true
86+
await exception.handle()
87+
88+
const UserException = await fs.get('app/Exceptions/Custom/UserException.ts')
89+
const ExceptionTemplate = await templates.get('self-handle-exception.txt')
90+
assert.deepEqual(
91+
toNewlineArray(UserException),
92+
toNewlineArray(ExceptionTemplate.replace('${filename}', 'UserException')),
93+
)
94+
})
95+
})

test/make-listener.spec.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,8 @@ test.group('Make Listener', (group) => {
5656
eventListeners: 'App/Events/Listeners',
5757
},
5858
aliases: {
59-
App: './app'
60-
}
59+
App: './app',
60+
},
6161
}))
6262

6363
const app = new Application(fs.basePath, new Ioc(), {}, {})

0 commit comments

Comments
 (0)