diff --git a/client/instanceProxyHandler.js b/client/instanceProxyHandler.js
index 6c68ac68..f8f16647 100644
--- a/client/instanceProxyHandler.js
+++ b/client/instanceProxyHandler.js
@@ -1,5 +1,5 @@
import client from './client'
-import { generateContext } from './context'
+import context, { generateContext } from './context'
import { generateObjectProxy } from './objectProxyHandler'
export const instanceProxies = new WeakMap()
@@ -15,8 +15,22 @@ const instanceProxyHandler = {
}
const { [name]: named } = {
[name]: (args) => {
- const context = generateContext({ ...target._attributes, ...args })
- return target[name].call(proxy, context)
+ const scopedContext = generateContext({ ...target._attributes, ...args })
+ let result
+ try {
+ result = target[name].call(proxy, scopedContext)
+ } catch (error) {
+ context.catch && context.catch(error)
+ return null
+ }
+ if (result instanceof Promise) {
+ return new Promise((resolve, reject) => {
+ result.then(resolve).catch((error) => {
+ context.catch ? context.catch(error) : reject(error)
+ })
+ })
+ }
+ return result
},
}
return named
diff --git a/server/printError.js b/server/printError.js
index a2daa484..c375cf76 100644
--- a/server/printError.js
+++ b/server/printError.js
@@ -1,4 +1,7 @@
+import context from './context'
+
export default function (error) {
+ context.catch && context.catch(error)
const lines = error.stack.split(`\n`)
let initiator = lines.find((line) => line.indexOf('Proxy') > -1)
if (initiator) {
diff --git a/server/reqres.js b/server/reqres.js
index c743ad43..13cdb10c 100644
--- a/server/reqres.js
+++ b/server/reqres.js
@@ -1,2 +1,20 @@
-const reqres = {}
+class ReqRes {
+
+ request = null
+ response = null
+
+ set(request, response) {
+ this.request = request
+ this.response = response
+ }
+
+ clear() {
+ this.request = null
+ this.response = null
+ }
+
+}
+
+const reqres = new ReqRes()
+
export default reqres
diff --git a/server/server.js b/server/server.js
index dac39bb9..96766186 100644
--- a/server/server.js
+++ b/server/server.js
@@ -40,6 +40,7 @@ for (const method of ['get', 'post', 'put', 'patch', 'delete', 'all']) {
server[method] = function (...args) {
if (typeof args[1] === 'function' && args[1].name === '_invoke') {
return original(args[0], bodyParser.text({ limit: server.maximumPayloadSize }), async (request, response) => {
+ reqres.set(request, response)
const params = {}
for (const key of Object.keys(request.params)) {
params[key] = extractParamValue(request.params[key])
@@ -53,9 +54,11 @@ for (const method of ['get', 'post', 'put', 'patch', 'delete', 'all']) {
try {
const subcontext = generateContext({ request, response, ...params })
const result = await args[1](subcontext)
+ reqres.clear()
response.json(result)
} catch (error) {
printError(error)
+ reqres.clear()
response.status(500).json({})
}
})
@@ -224,6 +227,7 @@ server.start = function () {
server.all(`/${prefix}/:hash/:methodName.json`, async (request, response) => {
const payload = request.method === 'GET' ? request.query.payload : request.body
+ reqres.set(request, response)
const args = deserialize(payload)
const { hash, methodName } = request.params
const [invokerHash, boundHash] = hash.split('-')
@@ -241,12 +245,15 @@ server.start = function () {
try {
const subcontext = generateContext({ request, response, ...args })
const result = await method.call(boundKlass, subcontext)
+ reqres.clear()
response.json({ result })
} catch (error) {
printError(error)
+ reqres.clear()
response.status(500).json({})
}
} else {
+ reqres.clear()
response.status(404).json({})
}
})
@@ -255,21 +262,23 @@ server.start = function () {
if (request.originalUrl.split('?')[0].indexOf('.') > -1) {
return next()
}
- reqres.request = request
- reqres.response = response
+ reqres.set(request, response)
const scope = await prerender(request, response)
if (!response.headersSent) {
const status = scope.context.page.status
const html = template(scope)
- reqres.request = null
- reqres.response = null
+ reqres.clear()
response.status(status).send(html)
} else {
- reqres.request = null
- reqres.response = null
+ reqres.clear()
}
})
+ server.use((error, _request, response, _next) => {
+ printError(error)
+ response.status(500).json({})
+ })
+
if (!server.less) {
if (!server.port) {
console.info('\x1b[31mServer port is not defined!\x1b[0m')
diff --git a/tests/client.js b/tests/client.js
index 24b58b0e..5fe6e42f 100644
--- a/tests/client.js
+++ b/tests/client.js
@@ -1,6 +1,7 @@
import Nullstack from 'nullstack'
import Application from './src/Application'
+import CatchError from './src/CatchError.njs'
import vueable from './src/plugins/vueable'
Nullstack.use(vueable)
@@ -12,4 +13,9 @@ context.start = function () {
setTimeout(() => (context.startTimedValue = true), 1000)
}
+context.catch = async function (error) {
+ CatchError.logError({ message: error.message })
+ console.error(error)
+}
+
export default context
diff --git a/tests/server.js b/tests/server.js
index 62df2bbb..715265c4 100644
--- a/tests/server.js
+++ b/tests/server.js
@@ -3,12 +3,14 @@ import Nullstack from 'nullstack'
import cors from 'cors'
import Application from './src/Application'
+import CatchError from './src/CatchError'
import ContextProject from './src/ContextProject'
import ContextSecrets from './src/ContextSecrets'
import ContextSettings from './src/ContextSettings'
import ContextWorker from './src/ContextWorker'
import ExposedServerFunctions from './src/ExposedServerFunctions'
import vueable from './src/plugins/vueable'
+import ReqRes from './src/ReqRes'
Nullstack.use(vueable)
@@ -40,6 +42,9 @@ context.server.put('/data/put/:param', ExposedServerFunctions.getData)
context.server.patch('/data/patch/:param', ExposedServerFunctions.getData)
context.server.delete('/data/delete/:param', ExposedServerFunctions.getData)
+context.server.get('/exposed-server-function-url.json', ReqRes.exposedServerFunction)
+context.server.get('/nested-exposed-server-function-url.json', ReqRes.nestedExposedServerFunction)
+
context.server.get('/custom-api-before-start', (request, response) => {
response.json({ startValue: context.startValue })
})
@@ -57,6 +62,10 @@ for (const method of methods) {
})
}
+context.server.get('/vaidamerdanaapi.json', (_request, response) => {
+ response.vaidamerdanaapi()
+})
+
context.startIncrementalValue = 0
context.start = async function () {
@@ -68,4 +77,9 @@ context.start = async function () {
context.startIncrementalValue++
}
+context.catch = async function (error) {
+ CatchError.logError({ message: error.message })
+ console.error(error)
+}
+
export default context
diff --git a/tests/src/Application.njs b/tests/src/Application.njs
index 25ff8241..997742df 100644
--- a/tests/src/Application.njs
+++ b/tests/src/Application.njs
@@ -4,6 +4,7 @@ import AnchorModifiers from './AnchorModifiers'
import './Application.css'
import ArrayAttributes from './ArrayAttributes'
import BodyFragment from './BodyFragment'
+import CatchError from './CatchError'
import ChildComponent from './ChildComponent'
import ComponentTernary from './ComponentTernary'
import Context from './Context'
@@ -40,6 +41,7 @@ import PublicServerFunctions from './PublicServerFunctions.njs'
import PureComponents from './PureComponents'
import Refs from './Refs'
import RenderableComponent from './RenderableComponent'
+import ReqRes from './ReqRes'
import RoutesAndParams from './RoutesAndParams'
import RouteScroll from './RouteScroll'
import ServerFunctions from './ServerFunctions'
@@ -137,6 +139,8 @@ class Application extends Nullstack {
+
+