Skip to content

Commit f366504

Browse files
authored
Merge pull request #63 from mgrandrath/set_retry-after_header_when_throwing
Set 'Retry-After' header when throwing error
2 parents ae755c8 + cd80e1f commit f366504

File tree

3 files changed

+17
-6
lines changed

3 files changed

+17
-6
lines changed

index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@ module.exports = function ratelimit (opts = {}) {
107107
ctx.body = opts.errorMessage || `Rate limit exceeded, retry in ${ms(delta, { long: true })}.`
108108

109109
if (opts.throw) {
110+
headers['Retry-After'] = after
110111
ctx.throw(ctx.status, ctx.body, { headers })
111112
}
112113
}

test/memory.spec.js

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,18 +63,20 @@ describe('ratelimit middleware with memory driver', () => {
6363
describe('limit with throw', () => {
6464
let guard
6565
let app
66+
let errorWasThrown
6667

6768
const hitOnce = () => guard.should.equal(1)
6869

6970
beforeEach(async () => {
7071
app = new Koa()
72+
errorWasThrown = false
7173

7274
app.use(async (ctx, next) => {
7375
try {
7476
await next()
7577
} catch (e) {
76-
ctx.body = e.message
77-
ctx.set(Object.assign({ 'X-Custom': 'foobar' }, e.headers))
78+
errorWasThrown = true
79+
throw e
7880
}
7981
})
8082

@@ -103,10 +105,13 @@ describe('ratelimit middleware with memory driver', () => {
103105
it('responds with 429 when rate limit is exceeded', async () => {
104106
await request(app.listen())
105107
.get('/')
106-
.expect('X-Custom', 'foobar')
107108
.expect('X-RateLimit-Remaining', '0')
109+
.expect('Retry-After', '0')
108110
.expect((res) => res.error.text.should.match(/^Rate limit exceeded, retry in.*/))
109111
.expect(429)
112+
.then(() => {
113+
errorWasThrown.should.equal(true)
114+
})
110115
})
111116
})
112117

test/redis.spec.js

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,18 +61,20 @@ describe('ratelimit middleware with redis driver', () => {
6161
describe('limit with throw', () => {
6262
let guard
6363
let app
64+
let errorWasThrown
6465

6566
const hitOnce = () => guard.should.equal(1)
6667

6768
beforeEach(async () => {
6869
app = new Koa()
70+
errorWasThrown = false
6971

7072
app.use(async (ctx, next) => {
7173
try {
7274
await next()
7375
} catch (e) {
74-
ctx.body = e.message
75-
ctx.set(Object.assign({ 'X-Custom': 'foobar' }, e.headers))
76+
errorWasThrown = true
77+
throw e
7678
}
7779
})
7880

@@ -102,10 +104,13 @@ describe('ratelimit middleware with redis driver', () => {
102104
it('responds with 429 when rate limit is exceeded', async () => {
103105
await request(app.listen())
104106
.get('/')
105-
.expect('X-Custom', 'foobar')
106107
.expect('X-RateLimit-Remaining', '0')
108+
.expect('Retry-After', '0')
107109
.expect((res) => res.error.text.should.match(/^Rate limit exceeded, retry in.*/))
108110
.expect(429)
111+
.then(() => {
112+
errorWasThrown.should.equal(true)
113+
})
109114
})
110115
})
111116

0 commit comments

Comments
 (0)