how to catch a server error in sapper (svelte)
Asked Answered
H

1

10

I am translating my little website from express+handlebars to an express+sapper project.

I would like to catch server side errors (for instance, a voluntary error when you go to /api/error) and render them using the sapper _error.svelte template.

I tried just throwing the error without my custom handler, but it returns an ugly text page with only the error stack, and does not seem to be catched by sapper's error handler

so I added my own error handler, and I can render HTML (bare, with no css yet) but is there a way I could use the sapper _error.svelte template ?

// ----------------------- src/server.js
import sirv from 'sirv'
import express from 'express'
import compression from 'compression'
import * as sapper from '@sapper/server'

import fatal500 from './middlewares/fatal500'

const { PORT, NODE_ENV } = process.env
const dev = NODE_ENV === 'development'

const app = express()

app.use(compression({ threshold: 0 }))
app.use(sirv('static', { dev }))

// the voluntary error thrower --------------------------------
app.get('/api/error', (req, res, next) => {
  const error = new Error('this is a voluntary error')
  error.code = 'VOLUNTARY'
  next(error)
})

app.use(sapper.middleware())

app.use(fatal500) // the custom error handler -----------

app.listen(PORT, err => {
  if (err) console.log('error', err)
})

// ---------------------src/middlewares/fatal500.js

export default function fatal500 (err, req, res, next) {
  if (err.code !== 'VOLUNTARY') console.error(err.stack)

  try {
    res.status(500)
      .type('html')
      .send(
        '<h1>Oooops ... 500 server error</h1>' +
        '<p>It seems the server has encountered an error,<br/>' +
        '   try to <a href=\'/\'> return to the website</a><br/>' +
        '   or to <a href="mailto:[email protected]">send me the stack</a>' +
        '</p>' +
        '<h2>Error Stack :</h2>' +
        '<pre class="code"><code>' +
        err.stack +
        '</code></pre>'
      )
  } catch (e) {
    res.status(500)
      .type('text')
      .send(
        '\n\n' +
        '**************************************\n' +
        'Ooops ... 500\n' +
        'the server encountered an unhandled error,\n\n' +
        'if it is not voluntary (going to /api/error)\n' +
        'please EMAIL ME THE FOLLOWING STACK at\n' +
        '[email protected]\n' +
          '**************************************\n\n' +
        'ORIGINAL ERROR STACK ------------------\n\n' +
        err.stack + '\n\n' +
        'ERROR HANDLING STACK ------------------\n\n' +
        e.stack
      )
  }
}
Hiroko answered 21/2, 2020 at 15:19 Comment(4)
I'm also having this issue.Orleans
Sapper's error handling is extremely unstable. By that I mean you will get different results based on how the error happened -> for example, server-side error handling generally works, but errors when navigating on client (99% normal usage) are not and the page will break and no error component be shown. I think this only happens when an uncaught promise error happens, but sapper does not catch its own errors. Don't expect any of this to be fixed as sapper has practically been abandoned due to lack of popularity.Relate
Sapper has been put into maintenance because we're releasing Svelte Kit, not due to lack of popularity.Regen
I read about svelte kit a few days ago and I can't wait to see what it's going to be. I'm really happy with svelte and I hope it reaches maturity soon.Hiroko
R
1

Javascript is notoriously difficult to catch all types of error in. Sapper doesn't have any explicit handling for these errors either, however there is a neat third party component which allows this.

The first way, which I personally use, is this library: https://www.npmjs.com/package/@crownframework/svelte-error-boundary

Which essentially will catch errors (within reason) at the boundary of a component. It provides a way to attach a function so that you can then do what you like with that error.

I'm currently in the process of building this into Svelte itself. You can feed back on the RFC https://github.com/sveltejs/rfcs/blob/rfc/error-boundary/text/0000-error-boundary.md

The way in which I use the boundary is that I attach the handler to sentry - https://sentry.io which will break down and diagnose issues for you, so that you can fix them. Take a look!

Regen answered 15/3, 2021 at 19:12 Comment(1)
Thanks for the tip, I am rebuilding my website leaving sapper for a simpler SPA but keeping svelte. I will add the package while this functionality be included.Hiroko

© 2022 - 2024 — McMap. All rights reserved.