Error handling
This page is about handling bugs, expected errors, and network errors.
- To block unauthorized access: Guides > Permissions
- To handle invalid
<form>
values: Guides > Form validation- To install error tracking: API >
onBug()
Bugs
If a telefunction has a bug:
// hello.telefunc.js
// Environment: server
export { hello }
function hello(name) {
// This telefunction has a bug: it should be `name` instead of `namee`
return 'Hello ' + namee
}
Then a telefunction call throws an error:
<!-- index.html -->
<!-- Environment: client -->
<html>
<body>
<script type="module">
import { hello } from './hello.telefunc.js'
try {
await hello('Eva')
console.log("I'm never printed")
} catch(err) {
console.log(err.message) // Prints 'Internal Server Error'
// E.g. show a popup "Something went wrong. Try again (later)."
// ...
}
</script>
</body>
</html>
To avoid leaking sensitive information, Telefunc doesn't send the original
Error
object to the frontend.
Expected Errors
An error thrown by a telefunction may not be a bug but an expected error instead.
For example:
- Some authentication libraries throw an error if the user isn't logged in.
- Some validation libraries throw errors upon invalid data.
We can:
- Propagate the error to the frontend, or
- handle the error on the server-side.
1. Propagate the error to the frontend.
We can propagate error information to the frontend like this:
import { validate } from 'some-library'
function onFromSubmit(data) {
try {
validate(data)
} catch(err) {
return {
errorMessage: `Data is invalid: ${err.message}. Please enter valid data.`
}
}
}
We can also use throw Abort(someValue)
:
import { validate } from 'some-library'
import { Abort } from 'telefunc'
function onFromSubmit(data) {
try {
validate(data)
} catch(err) {
throw Abort({
errorMessage: `Data is invalid: ${err.message}. Please enter valid data.`
})
}
}
In general, we recommend using return { someValue }
instead of throw Abort(someValue)
, see explanation at Guides > Form validation > throw Abort(someValue)
.
We need to catch the error and use
throw Abort(someValue)
because Telefunc doesn't send the originalError
object to the frontend (in order to avoid leaking sensitive information).
Also see Guides > Permissions > getContext()
wrapping.
2. Handle the error on the server-side.
We can handle the thrown error at our Telefunc server middleware:
// server.js
// Server (Express.js/Fastify/...)
import { telefunc } from 'telefunc'
// Telefunc middleware
app.all('/_telefunc', async (req, res) => {
const httpResponse = await telefunc(/* ... */)
// Telefunc exposes any error thrown by a telefunction at httpResponse.err
if (httpResponse.err) {
// Our error handling
}
})
Also see API > getContext()
> Provide.
Network Errors
If the user's browser can't connect to our server:
<!-- index.html -->
<!-- Environment: client -->
<html>
<body>
<script type="module">
import { hello } from './hello.telefunc.js'
try {
await hello('Eva')
} catch(err) {
if (err.isConnectionError) {
// There is a network problem:
// - the user isn't connected to the internet, or
// - our server is down.
console.log(err.message) // Prints 'No Server Connection'
}
}
</script>
</body>
</html>