I’m writing an API for a custom integration, and u...
# suitescript
j
I’m writing an API for a custom integration, and using a restlet as the endpoint for POST and GET calls. I have some error checking in place and want to be able to throw an error with a custom message in some scenarios. I can do the following and get back a 400 in Postman:
Copy code
throw error.create({
	name: 'FAILURE',
	message: 'Here is my error message',
	notifyOff: false
});
In Postman I get this:
Copy code
{
  "error": {
    "code": "FAILURE",
    "message": "{\"type\":\"error.SuiteScriptError\",\"name\":\"FAILURE\",\"message\":\"Here is my error message\",\"id\":null,\"stack\":[\"Error\",\"    at <http://Object.post|Object.post> (/SuiteScripts/2.0/restlet/rl_api_ss2.1.js:160:16)\"],\"cause\":{\"name\":\"FAILURE\",\"message\":\"Here is my error message\",\"notifyOff\":false},\"notifyOff\":false,\"userFacing\":true}"
  }
}
How would I instead get this in Postman:
Copy code
{
  "error": {
    "code": "FAILURE",
    "message": "Here is my error message"
  }
}
I don’t need all the other stuff and the team I’m integrating with doesn’t want all the rest of that message.
n
Just don’t create an error object when you throw the error.
Copy code
throw JSON.stringify({name: “some name”, message: “error message”})
The error.create() is creating the error object you are seeing in postman with the extra stack and stuff. Throw will error with whatever you give it, it doesn’t necessarily have to be an error object
a
yeah all this ^ 🙂
j
ooh
ok
is there a way to put something in the
code
though?
a
just create your object that way
Copy code
throw JSON.stringify({code: "FAILURE", message: "rethink your life choices"})
😂 3
j
lol
it’s still going one level too deep tho
Copy code
{
  "error": {
    "code": "",
    "message": "{\"code\":\"FAILURE\",\"message\":\"rethink your life choices\"}"
  }
}
I just want
{ “error”: { “code”: “FAILURE”, “message”: “rethink your life choices” } }
a
umm what if you don't stringify it?
n
How are you returning out of your RESTlet with the errors
☝️ 1
j
then I lose the FAILURE
I just returning straight after
throw {code: “FAILURE”, message: “rethink your life choices”}; return;
gives me this:
{ “error”: { “code”: “”, “message”: “rethink your life choices” } }
but still a 400 which is good
a
but what does your restlet response code look like?
j
do you mean this?
a
your RESTlet code to write a response
n
Copy code
const post = (context) => {
//some super complex code

 return somethingHere;
}
The something here part
j
for privacy had to delete out a bunch of stuff here, but here’s the skeleton of the script
Copy code
/**
 * @NApiVersion 2.1
 * @NScriptType restlet
 *
 * last modified 2024-04-02 JB
 */
define(['N/error', 'N/runtime',
	'/SuiteScripts/2.0/module/md_api_ss2.1',
	'/SuiteScripts/2.0/module/md_box_ss2.1',
	'/SuiteScripts/2.0/module/md_integration_ss2.1',
	'/SuiteScripts/2.0/module/md_integrity_ss2.1'],
	function(error, runtime, md_api, md_box, md_integration, md_integrity) {

	function get(get_data) {

		try {

			// a bunch of logic here to handle the get request

			return JSON.stringify(result);

		} catch(e) {

			log.debug({title: 'GET Error', details: e.message});

			// Email Jen.
			email.send({
				author: 19440,
				recipients: [12227],
				subject: 'NetSuite Restlet API Error (GET): ' + e.message,
				body: 'NetSuite Restlet API Error (GET): ' + e.message + "\n\nPAYLOAD: " + JSON.stringify(get_data)
			});

			throw {code: "FAILURE", message: e.message};

			return;

		}

	}

	function post(post_data) {

		try {

			// a bunch of logic here to handle the post request

			return JSON.stringify(result);

		} catch(e) {

			log.debug({title: 'POST Error', details: e.message});

			throw {code: "FAILURE", message: e.message};

			return;

		}

	}

	return {
		get: get,
		post: post
	}

});
the // has actual code in it obviously, to do the non-error work
n
Woah.. I did not know that throwing an error would automatically return out of the suitelet with a 400
💯 1
j
restlet
but yes
as does any other error e.g. some other deeper fail
UNEXPECTED ERROR or INVALID VALUE or whatever
n
Right oops. My brains been on suitelets all day. We just had this conversation last week in another thread about how that wasn’t possible lol
j
not the end of the world if I can’t return a
code
the Mulesoft guys wanted something other than a 400 error, I already am not doing what they want lol
I’m like…. have your system read the message, do different things with it? shouldn’t be that hard….
n
In that case the error payload you are receiving is handled by internal netsuite code. So you likely won’t be able to control it. Instead of Throw error Then return Just return the JSON.stringify(errorObj)
Ditch the throw and return the rest
j
needs to be a 400
at least
something other than 200 OK
I think this is close enough
still better than when I started this thread!
a
so you're throwing again in your catch... can you not just return there instead of throwing it?
Copy code
} catch(e) {

			log.debug({title: 'POST Error', details: e.message});

			return JSON.stringify({code: "FAILURE", message: e.message});

		}
j
if I do that, it doesn’t 400
a
I thought they didn't want a 400? oh i misread that part
j
ideally they’d want different flavours in the 400s
a
okay... so you need to throw to get the 400 HTTP status code, that's just NS rules what do you see in post man if you do this...
Copy code
} catch(e) {

			log.debug({title: 'POST Error', details: e.message});

			throw JSON.stringify({code: "FAILURE", message: e.message});

		}
versus this?
Copy code
} catch(e) {

			log.debug({title: 'POST Error', details: e.message});

			throw {code: "FAILURE", message: e.message};

		}
sorry for edits
but honestly I think the real thing here is to tell them if you want good error message then you have to write them as a response, which means it WILL be a 200 response... its a trade off that they'll need to parse and figure out on their side, so maybe just find which is the best compromise?
j
in both above I get nothing in code, in the first I’d get that object stringified in message, in the latter the message would just be the e.message
it’s all good
code blank = Jen threw the error on purpose, code non-blank = NS threw an error
a
cos if its something like bad data... a retry won't fix it? I'd assume if its a 5xx error they just retry, but a 4xx means retry probably isn't viable, so at that point they need to parse the error message and figure out what went wrong
j
so maybe that’s good
yeah exactly this is the part I’m getting them to sort out. As it is, when they get any error they are sending again every 15 minutes
which has been … fun
each makes a support case
assigned to me
😐
a
ROFLMAO
j
suboptimal
a
k well sounds like you're on it
j
Thanks for all the help
👍 1
a
not sure I did much this time, but your problems are always fun... @Nathan L did the useful stuff
n
A joint effort for sure. But anytime you need it I’m always available to jump in and talk a lot without actually helping🫡
😂 1
😄 1
Jen really does always have the fun stuff
😂 1
a
right? they're the best cos they're interesting and she provides all the useful info... and i have absolutely no responsibility to actually fix anything 😂
n
It’s like my dream job lol Solve fun puzzles until it’s too hard then just leave haha
💯 2
b
be very careful here, the error handling code is different between suitescript 2.1 and 2.0
from your description, it looks like you are using suitescript 2.1
in which case the code actually comes from the name property
you want to throw
Copy code
{name: "FAILURE", message: "rethink your life choices"}
in general this goes under tricking suitescript's error handling code, so you probably dont want to build anything critical on this
it can change without warning
j
lol
fun
😂 1
I save the good stuff for you guys
Using
name
instead of
code
worked, thank you so much @battk
s
or rather, throw native javascript -
throw new Error(...)
Also, since we do not have good control over NS HTTP response codes, we tell users to consider the response code 'network level' and we include our own errors in the application layer response.
Hence, an HTTP 200 means the low level request made it, but there may still be application level errors that can be in the response.
an HTTP 400 or 500 implies something broke and the request didn't actually successfully make it to our code.
incidentally, this pattern also allows representing partial success/failure as I've mentioned a few times before. In that scenario, you still have a 200 HTTP response because the code actually had a chance to process the request, and the response may include a combination of success and error information. Can't really represent that with just the HTTP codes we can return from NS.
121 Views