# Doc inconsistencies around responses and basic function template

**URL:** <https://answers.netlify.com/t/doc-inconsistencies-around-responses-and-basic-function-template/122296>\
**Category:** Support\
**Tags:** lambda-functions\
**Created:** [July 18, 2024, 12:58pm UTC](https://answers.netlify.com/t/doc-inconsistencies-around-responses-and-basic-function-template/122296 "2024-07-18T12:58:18Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![digerata](https://sea1.discourse-cdn.com/netlify/user_avatar/answers.netlify.com/digerata/32/20891_2.png) [@digerata](https://answers.netlify.com/u/digerata)\
**Post date:** [July 18, 2024, 12:58pm UTC](https://answers.netlify.com/t/doc-inconsistencies-around-responses-and-basic-function-template/122296/1 "2024-07-18T12:58:18Z")

</div>

Happy Netlify customer here for many years.

It looks like Netlify docs & functions are in the middle of a transition? Which really stinks if you are a newbie coming in and trying out Functions functionality.

I just spent an evening and a morning trying to figure out how to return a status code using the default recommended function template:

All of the docs show this:

```javascript
export default async (req, context) => {
  return new Response("Hello, world!");
};

```

(Link: [Get started with functions | Netlify Docs](https://docs.netlify.com/functions/get-started/?fn-language=js#synchronous-function-2))

Which appears to be the new blessed way to do this.

But if you go through the rest of the docs, the following format is used:

```javascript
const handler: Handler = async function (event: HandlerEvent, context: HandlerContext) {
   //...
}

```

And if you aren’t paying close attention, you’ll miss that. It’s cognitive overload that one doesn’t need when you are scanning info on how to do something: “Is this the old way or the new way?”

Now to the point: how do you return a 404 status code along with some JSON?

Well, looking at the Netlify docs, it’s quite obviously:

```javascript
return {
  body: JSON.stringify({}),
  statusCode: 404
}

```

And, that’s also further cemented as the way according to all the searches here on [answers.netlify.com](http://answers.netlify.com) and [google.com](http://google.com)

But it’s not. It’s:

```javascript
return new Response(JSON.stringify({}), { status: 404 });

```

(Which I only figured out by going through Mozilla developer docs: [Response: Response() constructor - Web APIs | MDN](https://developer.mozilla.org/en-US/docs/Web/API/Response/Response))

And to my last point, finding out WHY you are getting a blank 500 error code with absolutely no exception thrown, no error message, nothing in the logs on development and production is really, really frustrating.

It appears (and maybe this was stated in the docs some place that I missed) that if you access the function locally in a browser, instead of via a JS fetch or RapidAPI test call, you will get an HTML page that explains more and includes a stack trace.

 ![CleanShot 2024-07-18 at 08.54.27](https://global.discourse-cdn.com/netlify/original/3X/1/a/1ae476cdc1f356237ba489fdfc916ac7a88a9ddd.png)

But why oh why isn’t that message shown in the local CLI logs? I only stumbled upon this by accident.

Some of this is me venting. But mostly this is feedback to improve the docs and also for anyone else that comes through here in the future trying to find out how to return a response with a status code from a Function.

---

<div class="post-metadata">

**Author:** ![digerata](https://sea1.discourse-cdn.com/netlify/user_avatar/answers.netlify.com/digerata/32/20891_2.png) [@digerata](https://answers.netlify.com/u/digerata)\
**Post date:** [July 18, 2024, 1:50pm UTC](https://answers.netlify.com/t/doc-inconsistencies-around-responses-and-basic-function-template/122296/2 "2024-07-18T13:50:26Z")

</div>

Further:

How do you use JSON sent to a function?

Do you read it from the body?

```javascript
let body = JSON.parse(req.body);

```

No, that kills the function. (Also, in my testing, it kills it so hard that 9 of 10 console.log statements are not shown in the cli logs. Which, again, is problematic if you are use logging to debug problems.)

So what is req.body? Can I just output the value?

```javascript
console.log(req.body);

```

Yields exactly nothing. A blank. Even if the body did actually have content.

So from here one would search something like “netlify function request body is always blank” and you would get a list of forum posts here that talk about a bug in the CLI or improperly formatted JSON. A lot of posts that lead you to believe there is something wrong outside of your function code.

But that’s wrong. Buried in one of those posts is:

> [@Function body is apparently readablestream?](https://answers.netlify.com/t/function-body-is-apparently-readablestream/110146):
>
> I have a fetch request like this: fetch('/.netlify/functions/get-image', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({test: 'test'}) }) And a function called get-image.js like this: export default async (request, context) =\> { console.log(request.body); } The request.body is always a ReadableStream instead of JSON. This happens on dev and prod. I can get it working with await request.json(), but I’m unsure why this is …

And reading there, you finally find the answer:

```javascript
req.json()

```

The answer refers to a Netlify blog post describing the change. Why isn’t this referring to the docs instead? Blog posts aren’t coming up in searches for dev issues.

---

<div class="post-metadata">

**Author:** ![hrishikesh](https://sea1.discourse-cdn.com/netlify/user_avatar/answers.netlify.com/hrishikesh/32/74607_2.png) [@hrishikesh](https://answers.netlify.com/u/hrishikesh)\
**Post date:** [July 19, 2024, 2:55pm UTC](https://answers.netlify.com/t/doc-inconsistencies-around-responses-and-basic-function-template/122296/3 "2024-07-19T14:55:23Z")

</div>

A lot of this post, as you mentioned, seems for venting. This is less of a help me troubleshoot post and more of frustration due to hours spent. While I understand that, I’m sorry to be the person to blame this (at least partially) on the user.

I’d have taken this feedback, but this does look like a reading error on your end. I could be wrong and I’d be happy to learn more about the _exact_ pieces of docs you found with the issue, which currently you have not linked.

> [@digerata](#):
>
> All of the docs show this:
> 
> ```auto
> export default async (req, context) => {
> return new Response("Hello, world!");
> };
> 
> ```
> 
> (Link: [Get started with functions | Netlify Docs](https://docs.netlify.com/functions/get-started/?fn-language=js#synchronous-function-2))
> 
> Which appears to be the new blessed way to do this.

This part is correct.

> [@digerata](#):
>
> But if you go through the rest of the docs, the following format is used:
> 
> ```auto
> const handler: Handler = async function (event: HandlerEvent, context: HandlerContext) {
> //...
> }
> 
> ```
> 
> And if you aren’t paying close attention, you’ll miss that. It’s cognitive overload that one doesn’t need when you are scanning info on how to do something: “Is this the old way or the new way?”

I found that section in Functions and Identity section: [Functions and Identity | Netlify Docs](https://docs.netlify.com/functions/functions-and-identity/), which is not somewhere a user who doesn’t use Identity would go. Furthermore, that’s the only way to use Functions + Identity, so this is at least not a case of incorrect documentation. If you found the old syntax elsewhere, we can get that updated.

> [@digerata](#):
>
> Now to the point: how do you return a 404 status code along with some JSON?

This is documented [Get started with functions | Netlify Docs](https://docs.netlify.com/functions/get-started/#synchronous-function-2):

> The handler function should return a [`Response` object](https://developer.mozilla.org/en-US/docs/Web/API/Response) representing the HTTP response to be delivered to the client.

We switched to a web-standard specifically so that you don’t have to learn Netlify-specific concepts. Response has a json method: [Response: json() static method - Web APIs | MDN (mozilla.org)](https://developer.mozilla.org/en-US/docs/Web/API/Response/json_static), and the options accept a status code: [Response: json() static method - Web APIs | MDN (mozilla.org)](https://developer.mozilla.org/en-US/docs/Web/API/Response/json_static#options). This is how it can be put together:

```auto
return Response.json({
  msg: 'not-found'
}, {
  status: 404
})

```

> [@digerata](#):
>
> Well, looking at the Netlify docs, it’s quite obviously:
> 
> ```auto
> return {
> body: JSON.stringify({}),
> statusCode: 404
> }
> 
> ```

Source?

> [@digerata](#):
>
> And, that’s also further cemented as the way according to all the searches here on [answers.netlify.com](http://answers.netlify.com) and [google.com](http://google.com)

We had the Lambda API from 2019-2023. It’s not a surprise most of the old posts still show that as it’s not possible to update every post with the new syntax.

> [@digerata](#):
>
> (Which I only figured out by going through Mozilla developer docs: [Response: Response() constructor - Web APIs | MDN](https://developer.mozilla.org/en-US/docs/Web/API/Response/Response))

That’s the expectation, as mentioned above.

> [@digerata](#):
>
> And to my last point, finding out WHY you are getting a blank 500 error code with absolutely no exception thrown, no error message, nothing in the logs on development and production is really, really frustrating.

This would be something we would have to investigate, but that sounds more of a complaint than asking for help with troubleshooting.

> [@digerata](#):
>
> It appears (and maybe this was stated in the docs some place that I missed) that if you access the function locally in a browser, instead of via a JS fetch or RapidAPI test call, you will get an HTML page that explains more and includes a stack trace.

The stacktrace also exists when using fetch.

> [@digerata](#):
>
> So what is req.body? Can I just output the value?

It’s standard JavaScript, not something specific to Netlify. Fetch depends on Request/Response. How do you read JSON in fetch? It’s basically the same.

If you’re expecting Netlify to document something that’s already documented by MDN as a Web Standard, I don’t think we have any plans to do that. If we have mentioned that the request argument is the Web Standard Request interface, that should explain the rest.

---

<div class="post-metadata">

**Author:** ![digerata](https://sea1.discourse-cdn.com/netlify/user_avatar/answers.netlify.com/digerata/32/20891_2.png) [@digerata](https://answers.netlify.com/u/digerata)\
**Post date:** [July 19, 2024, 5:51pm UTC](https://answers.netlify.com/t/doc-inconsistencies-around-responses-and-basic-function-template/122296/4 "2024-07-19T17:51:42Z")

</div>

For the logging issue:

When using the `netlify dev` command to run locally, the problem is that it’s possible in Function code for `console.log` to not output anything even though execution passes that line of code.

Further, the problem is that an exception is thrown, but the exception is swallowed somewhere down lower and not shown to the end developer in the terminal output.

Here is a sample test case where console.log fails to go to CLI output:

netlify/funtions/hello.mjs:

```javascript
export default async (req, context) => {
    console.log("First line");
    console.log("Second line");
    console.log("Third line");
    console.log("Fourth line");
    console.log("Fifth line");

    JSON.parse(req.body); // this is valid javascript, but as discussed, doesn't work, that's not the point here though.

    return new Response("What happened to the logs?");
};

```

src/pages/index.astro:

```html
<script>
    window.addEventListener('load', function () {
        fetch("/.netlify/functions/hello", {
            method: "POST",
            body: JSON.stringify({
                word: "to your mother"
            })
        });
    });
 </script>

```

Expected `netlify dev` terminal output:

```auto
Request from ::1: GET /.netlify/functions/hello
First line
Second line
Third line
Fourth line
Fifth line
Exception raised: [error message]
     [stack trace]
Response with status 500 in 273 ms.

```

Actual:

```auto
Request from ::1: POST /.netlify/functions/hello
First line
Response with status 500 in 316 ms.

```

Zip of minimal Astro project:  
[Missing console log example.zip](https://answers.netlify.com/uploads/short-url/9kgn8WihhxTs9Bhu0uObHx62bA7.zip) (84.2 KB)

1. Extract zip
2. Run `yarn install`
3. Run `ntl dev`
4. Open index in browser and check the console output as well as terminal output.

---

<div class="post-metadata">

**Author:** ![hrishikesh](https://sea1.discourse-cdn.com/netlify/user_avatar/answers.netlify.com/hrishikesh/32/74607_2.png) [@hrishikesh](https://answers.netlify.com/u/hrishikesh)\
**Post date:** [July 19, 2024, 6:24pm UTC](https://answers.netlify.com/t/doc-inconsistencies-around-responses-and-basic-function-template/122296/5 "2024-07-19T18:24:22Z")

</div>

> [@digerata](#):
>
> ` JSON.parse(req.body); // this is valid javascript, but as discussed, doesn't work, that's not the point here though.`

That’s **not** valid JavaScript. Syntax-wise, it is, functionality-wise it’s not. req.body is a stream, not a JSON string. I’d recommend you to read about Request and Response from MDN docs.

As for the issue reported, this appears to be a bug. I’ve filed it for the devs.

---

<div class="post-metadata">

**Author:** ![hrishikesh](https://sea1.discourse-cdn.com/netlify/user_avatar/answers.netlify.com/hrishikesh/32/74607_2.png) [@hrishikesh](https://answers.netlify.com/u/hrishikesh)\
**Post date:** [September 29, 2024, 3:01pm UTC](https://answers.netlify.com/t/doc-inconsistencies-around-responses-and-basic-function-template/122296/7 "2024-09-29T15:01:08Z")

</div>

The issue has been identified to be a Node.js limitation: [github.com/nodejs/node/issues/40961](https://github.com/nodejs/node/issues/40961)
