Skip to content
This repository has been archived by the owner on Jan 21, 2024. It is now read-only.

Null safety for stringifyNonJSON function #22

Open
jmjdamen opened this issue Sep 29, 2020 · 8 comments
Open

Null safety for stringifyNonJSON function #22

jmjdamen opened this issue Sep 29, 2020 · 8 comments

Comments

@jmjdamen
Copy link

jmjdamen commented Sep 29, 2020

When using the JSONLoggerModule::stringifyNonJSON(payload) function and the payload is null due to an error in a flow, the JSON logger throws an exception (which is quite valid as it can't parse null).
However, in Mule flows sometimes the payload can be null due to exceptions, at the moment this is causing the JSON Logger to throw an error itself.

When the content field is configured with the function mentioned above, the content field contains.
"content" : "Error parsing expression. See logs for details."

This is not a really big issue however the error thrown because of this is:

org.mule.extension.jsonlogger.internal.JsonloggerOperations

Failed parsing field: content
org.mule.runtime.core.api.expression.ExpressionRuntimeException: "You called the function 'AnonymousFunction' with these arguments: 
  1: String ("")
  2: Null (null)

But it expects arguments of these types:
  1: Any
  2: String
  3: Object

Currently we solved this by check for null values in the JSON loggers content.
payload: if (payload != null) (JSONLoggerModule::stringifyNonJSON(payload)) else ""

This contains a manual action and can easily be forgotten.
It would be great if the function itself contains a null check in the underlying code, or see the alternative below.
So that the default expression (shown below) in the JSON logger content field can be used without any issues;

import modules::JSONLoggerModule output application/json ---
{
    payload: JSONLoggerModule::stringifyNonJSON(payload) 
}

OR update the default expression to the one we used

i saw this can be done easily here , so we will probably start doing this ourselves, but everyone can benefit from this improval and it can be fixed in the function itself or in the schema with looks a bit more 'dirty'

import modules::JSONLoggerModule output application/json ---
{
     payload: if (payload != null) (JSONLoggerModule::stringifyNonJSON(payload)) else ""
}
@skuller
Copy link
Contributor

skuller commented Oct 16, 2020

@jmjdamen have you tried the latest version? I can't seem to be able to reproduce the issue with null payloads. Would be have a sample app to reproduce the issue?

@revelant-doug
Copy link
Contributor

I've bumped into this when logging after a GET request that had no body. (I just noticed it this morning, not sure why I haven't seen it before.)

@revelant-doug
Copy link
Contributor

Looks like it only happens if the GET request sets a content-type of application/json, which is not correct since there is no body with a GET request.

Seems like a client error - specifying the content is JSON when it's not.

@jmjdamen
Copy link
Author

@skuller yes we are using 2.0.1

The only way i can reproduce a similar error with a test app is to refer to a key in the payload that does not exist.
This i what i tried.

POST JSON body via Postman
{
"test": "1234"
}

Refer in JSON logger to a non existing field in JSON, which can occur due to an error or incomplete response from an API.

payload: JSONLoggerModule::stringifyNonJSON(payload.data)

This is not what happens in our actual services, we just log payload.
I am not able to reproduce it with empty payload, setting payloads to null, removing content-types, etc.

The only thing i noticed from our original error in the logs is from the stack trace.
Issue occurred with a JSON logger that was in an error handler.

This was in the stacktrace of an error before it went into the JSON logger in that error handler.

Payload : null
Payload Type : null

@bcoveny
Copy link

bcoveny commented Feb 1, 2021

Hello @skuller @jmjdamen @revelant-doug ,

I seem to be getting this error rather often. In trying to understand the code more I used the Dataweave Playground (https://dwl.mule.club/) and if I copy the JSONLoggerModule into the script area and try to use it then it produces this error.

%dw 2.0
fun stringifyAny(inputData: Any) = if (inputData.^mimeType == "application/xml" or
									   inputData.^mimeType == "application/dw" or
									   inputData.^mimeType == "application/json") 
									write(inputData,inputData.^mimeType,{indent:false}) 
								   else if (inputData.^mimeType == "*/*")
								    inputData
								   else
						   	write(inputData,inputData.^mimeType)
						   	
fun stringifyNonJSON(inputData: Any) = if (inputData.^mimeType == "application/xml" or
										   inputData.^mimeType == "application/dw") 
										 write(inputData,inputData.^mimeType,{indent:false}) 
									   else if (inputData.^mimeType == "application/json" or inputData.^mimeType == "*/*")
									   	 inputData
									   else
							   			 write(inputData,inputData.^mimeType)

fun stringifyAnyWithMetadata(inputData: Any) = { 
												 data: if (inputData.^mimeType == "application/xml" or
														   inputData.^mimeType == "application/dw" or
														   inputData.^mimeType == "application/json")
														 write(inputData,inputData.^mimeType,{indent:false})
                                                       else if (inputData.^mimeType == "*/*")
                                                        inputData
													   else
													     write(inputData,inputData.^mimeType),													
												 (contentLength: inputData.^contentLength) if (inputData.^contentLength != null),
												 (dataType: inputData.^mimeType) if (inputData.^mimeType != null),
												 (class: inputData.^class) if (inputData.^class != null)
											   } 

fun stringifyNonJSONWithMetadata(inputData: Any) = { 
												 data: if (inputData.^mimeType == "application/xml" or
														   inputData.^mimeType == "application/dw")
														 write(inputData,inputData.^mimeType,{indent:false})
													   else if (inputData.^mimeType == "application/json" or inputData.^mimeType == "*/*")
													   	 inputData
													   else
													     write(inputData,inputData.^mimeType),													
												 (contentLength: inputData.^contentLength) if (inputData.^contentLength != null),
												 (dataType: inputData.^mimeType) if (inputData.^mimeType != null),
												 (class: inputData.^class) if (inputData.^class != null)
											   } 
output application/json
---
stringifyNonJSON(payload.message)

I have experienced the same error within flows where attempting to log the variables and there is no current variables defined and the map is blank.

I did attempt to patch myself and it lowered the number of errors that I was seeing but sometimes see a different error. Wanted to see if anyone had any thoughts on this first?

Thanks
Bruce

bcoveny pushed a commit to bcoveny/json-logger that referenced this issue Feb 1, 2021
…lank then will just return the initial inputData
@bcoveny
Copy link

bcoveny commented Feb 1, 2021

Here is the commit that I have changed locally that appears to resolve the issue as I am seeing it. Please provide feedback on these changes.

bcoveny@5dc7952

Thanks
Bruce

@esquerdo
Copy link

his i what i tried.

Hello guys!
I've just started using json logger and I would like to understand better the problem.
Do you know if the problem was fixed?
In order to prevent problems with null payload , is the "payload": JSONLoggerModule::stringifyNonJSON(payload) enought ?
Thank you!

@esquerdo
Copy link

esquerdo commented Nov 28, 2023

his i what i tried.

Hello guys! I've just started using json logger and I would like to understand better the problem. Do you know if the problem was fixed? In order to prevent problems with null payload , is the "payload": JSONLoggerModule::stringifyNonJSON(payload) enought ? Thank you!

I made some tests and works fine without an error, calling one get method without body:
{
"payload": payload

 }

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants