Skip to content

Commit

Permalink
🔧 fix: handle return error in transform, derive and resolve
Browse files Browse the repository at this point in the history
  • Loading branch information
SaltyAom committed Mar 18, 2024
1 parent ff9c1d3 commit 2fac801
Show file tree
Hide file tree
Showing 8 changed files with 74 additions and 31 deletions.
5 changes: 4 additions & 1 deletion CHANGELOG.md
@@ -1,10 +1,13 @@
# 1.0.1 - 18 Mar 2024
Improvement:
- mapHandler now check passthrough once instead of twice
- exclude `return error` from `derive` and `resolve`
- exclude return type of`ELYSIA_RESPONSE` type from `derive` and `resolve`
- throw error if `error` is return in `derive` and `resolve`
- handle `return error` on `transform`

Bug fix:
- explicit `type: 'json'` with body schema throw unexpected `body.Check` is not a function
- [#549](https://github.com/elysiajs/elysia/issues/495) await the .modules of nested Elysia instances

# 1.0.0 - 16 Mar 2024
Improvement:
Expand Down
23 changes: 11 additions & 12 deletions example/a.ts
@@ -1,18 +1,17 @@
import { Elysia, error, t } from '../src'
import { post, req } from '../test/utils'

const elysia1 = new Elysia()
const elysia2 = new Elysia()
const elysia3 = new Elysia()
const app = new Elysia()
.resolve(() => {
return error(418)

elysia3.get('/foo', () => 'foo')
elysia2.use(elysia3)
elysia1.use(elysia2)
return {
a: 'a'
}
})
.get('/', ({ a }) => a)
.listen(3000)

console.log(elysia1.routes)

elysia1.handle(
req('/foo')
)
.then((x) => x.text())
app.handle(req('/'))
.then((x) => x.status)
.then(console.log)
37 changes: 27 additions & 10 deletions src/compose.ts
Expand Up @@ -782,21 +782,23 @@ export const composeHandler = ({
unit: hooks.transform.length
})

fnLiteral += '\nlet transformed\n'

for (let i = 0; i < hooks.transform.length; i++) {
const transform = hooks.transform[i]

const endUnit = report('transform.unit', {
name: transform.name
})

if (transform.$elysia === 'derive')
fnLiteral += isAsync(transform)
? `Object.assign(c, await transform[${i}](c));`
: `Object.assign(c, transform[${i}](c));`
fnLiteral += isAsync(transform)
? `transformed = await transform[${i}](c)\n`
: `transformed = transform[${i}](c)\n`

fnLiteral += `if(transformed?.[ELYSIA_RESPONSE])
throw transformed
else
fnLiteral += isAsync(transform)
? `await transform[${i}](c);`
: `transform[${i}](c);`
Object.assign(c, transformed)\n`

endUnit()
}
Expand Down Expand Up @@ -954,6 +956,8 @@ export const composeHandler = ({
unit: hooks.beforeHandle.length
})

let hasResolve = false

for (let i = 0; i < hooks.beforeHandle.length; i++) {
const beforeHandle = hooks.beforeHandle[i]

Expand All @@ -964,17 +968,30 @@ export const composeHandler = ({
const returning = hasReturn(beforeHandle.toString())

// @ts-ignore
if (beforeHandle.$elysia === 'resolve') {
const isResolver = beforeHandle.$elysia === 'resolve'

if (isResolver) {
if (!hasResolve) {
hasResolve = true
fnLiteral += '\nlet resolved\n'
}

fnLiteral += isAsync(beforeHandle)
? `Object.assign(c, await beforeHandle[${i}](c));`
: `Object.assign(c, beforeHandle[${i}](c));`
? `resolved = await beforeHandle[${i}](c);\n`
: `resolved = beforeHandle[${i}](c);\n`

fnLiteral += `if(resolved[ELYSIA_RESPONSE])
throw resolved
else
Object.assign(c, resolved)\n`
} else if (!returning) {
fnLiteral += isAsync(beforeHandle)
? `await beforeHandle[${i}](c);\n`
: `beforeHandle[${i}](c);\n`

endUnit()
} else {
fnLiteral += `Object.assign(c, be);`
fnLiteral += isAsync(beforeHandle)
? `be = await beforeHandle[${i}](c);\n`
: `be = beforeHandle[${i}](c);\n`
Expand Down
6 changes: 3 additions & 3 deletions src/handler.ts
Expand Up @@ -116,7 +116,7 @@ export const mapResponse = (
// @ts-ignore
if (response?.$passthrough)
// @ts-ignore
response = response.$passthrough
response = response?.[response.$passthrough]

// @ts-ignore
if (response?.[ELYSIA_RESPONSE]) {
Expand Down Expand Up @@ -397,7 +397,7 @@ export const mapEarlyResponse = (
// @ts-ignore
if (response?.$passthrough)
// @ts-ignore
response = response.$passthrough
response = response?.[response.$passthrough]

// @ts-ignore
if (response?.[ELYSIA_RESPONSE]) {
Expand Down Expand Up @@ -676,7 +676,7 @@ export const mapCompactResponse = (
// @ts-ignore
if (response?.$passthrough)
// @ts-ignore
response = response.$passthrough
response = response?.[response.$passthrough]

// @ts-ignore
if (response?.[ELYSIA_RESPONSE])
Expand Down
2 changes: 1 addition & 1 deletion src/index.ts
Expand Up @@ -4957,7 +4957,7 @@ export default class Elysia<
* Wait until all lazy loaded modules all load is fully
*/
get modules() {
return Promise.resolve(this.promisedModules)
return Promise.all(this.promisedModules.promises)
}
}

Expand Down
4 changes: 2 additions & 2 deletions src/utils.ts
Expand Up @@ -721,8 +721,8 @@ export const isNumericString = (message: string): boolean => {
}

export class PromiseGroup implements PromiseLike<void> {
private root: Promise<any> | null = null
private promises: Promise<any>[] = []
root: Promise<any> | null = null
promises: Promise<any>[] = []

constructor(public onError: (error: any) => void = console.error) {}

Expand Down
14 changes: 13 additions & 1 deletion test/lifecycle/derive.test.ts
@@ -1,4 +1,4 @@
import { Elysia } from '../../src'
import { Elysia, error } from '../../src'

import { describe, expect, it } from 'bun:test'
import { req } from '../utils'
Expand Down Expand Up @@ -155,4 +155,16 @@ describe('derive', () => {

expect(total).toEqual(2)
})

it('handle error', async () => {
const app = new Elysia()
.derive(() => {
return error(418)
})
.get('/', () => '')

const res = await app.handle(req('/')).then((x) => x.text())

expect(res).toEqual("I'm a teapot")
})
})
14 changes: 13 additions & 1 deletion test/lifecycle/resolve.test.ts
@@ -1,4 +1,4 @@
import { Elysia } from '../../src'
import { Elysia, error } from '../../src'

import { describe, expect, it } from 'bun:test'
import { req } from '../utils'
Expand Down Expand Up @@ -184,4 +184,16 @@ describe('resolve', () => {

expect(total).toEqual(2)
})

it('handle error', async () => {
const app = new Elysia()
.resolve(() => {
return error(418)
})
.get('/', () => '')

const res = await app.handle(req('/')).then((x) => x.text())

expect(res).toEqual("I'm a teapot")
})
})

0 comments on commit 2fac801

Please sign in to comment.