Search code examples
sveltekitrate-limiting

return fail() in a server.js is producing error "return should return a response object"?


First time to use fail() in Sveltekit so I'm unable to figure out how to fix it.

I have a newsletter.svelte in $lib with a simple form to collect email addresses when user decide to subscribe to a newsletter :

$lib/components/newsletter.svelte :

<script>
    $: emailvalue = null

    async function emailsubscribe(){
        console.log("emailsubscribe fn fired...emailvalue log:", emailvalue)

        let posttheapi = await fetch('api/newsletter',{
        method : "POST",
        credentials : 'include',
        headers: {
        'Accept': 'application/json',
        'Content-type' : 'application/json'
        },
        body: JSON.stringify({
        useremail : emailvalue
        })
        })
        let postresults = await posttheapi.json()

        console.log("results log +page.svelte index page :", postresults )
    }

</script>


<form on:submit|preventDefault={emailsubscribe}>
    <div> 
    <label for="name">Email </label>
      <input type="email" name="email" placeholder="Type here" bind:value={emailvalue} />
    </div>
    <button> Subscribe </button>
</form>

inside routes/api/newsletter/+server.js here is what I do to capture the subscribed email address:

     import { RetryAfterRateLimiter } from 'sveltekit-rate-limiter/server';
     
     const limiter = new RetryAfterRateLimiter({
         //limiter options...
     })

    export async function POST(requestEvent){
    
      await limiter.cookieLimiter?.preflight(requestEvent);
    
        let readbody = await requestEvent.request.json()
        
       // Every call to isLimited counts as a hit towards the ratelimit for the event.
         
         const status = await limiter.check(requestEvent);
         
         if (status.limited) {
          requestEvent.setHeaders({
              'Retry-After': status.retryAfter.toString()
          });
          
          return fail(429);
          }
        
        let subscribedemail = readbody.useremail
        let success = true
        return json({success, subscribedemail})
    
    }

Is fail() only works in +page.server.js OR can I use it in +server.js too? If yes, I get the error "Error: Invalid response from route /api/newsletter: handler should return a Response object"

How can I fix this or how do I get it to work?


Solution

  • fail is not for custom endpoints (i.e. +server.js) but for form actions.

    This also looks like it just should be a form action (see the docs on how they work), those are in the +page.server.js file. On the client you would usually then use the enhance action on the form.

    For custom endpoints you would have to return a full Response object.