Is there any way to ignore "unexpected character" errors during deserialization (Newtonsoft)? - json.net

I have a contract whose json may or may not be in correct shape. The contract is this:
class TestContract
{
string TestString1;
string TestString2;
}
The json usually looks like this:
{ "TestString1": "Test", "TestString2": "Test" }
But it could look like this:
{ "TestString1": "Test", "TestString2":{ "Field": "Test" } }
The second case means something has gone wrong, but I do not want to throw an exception. I want to log that there is an issue, ignore TestString2 and proceed with the serialization.
In this case the resulting object should be the same as the one from this json string:
{ "TestString1": "Test" }
However, this seemingly cannot be handled with regular error handling (https://www.newtonsoft.com/json/help/html/SerializationErrorHandling.htm), because the error propagates up and the entire resulting object is null.
I don't see a reason why this shouldn't be able to be done, because the json is valid, just represents a slightly different object than the one I am deserializing into, just the same way as if you handle the error of trying to cast a string into an int. But I can't find any way to handle this. I saw a suggestion for using JsonReader, but it doesn't seem this can work as a generic solution. I need the error handling to take place no matter how complex the class and object are.
Anyone ever tried this before?

Related

The method '[]' was called on null. Receiver: null. Tried calling: []("myuserId") [duplicate]

I have some code and when I run it produces an error, saying:
NoSuchMethod: the method 'XYZ' was called on null
What does that mean and how do I fix it?
Why do I get this error?
Example
As a real world comparison, what just happened is this conversation:
Hey, how much gas is left in the tank of the car?
What are you talking about, we don't have a car.
That is exactly what is happening in your program. You wanted to call a function like _car.getGasLevel(); but there is no car, the variable _car is null.
Obviously, in your program it might not be a car. It could be a list or a string or anything else really.
Technical explanation
You are trying to use a variable that is null. Either you have explicitly set it to null, or you just never set it at all, the default value is null.
Like any variable, it can be passed into other functions. The place where you get the error might not be the source. You will have to follow the leads from the actual null value to where it originally came from, to find what the problem is and what the solution might be.
null can have different meanings: variables not set to another value will be null, but sometimes null values are used by programmers intentionally to signal that there is no value. Databases have nullable fields, JSON has missing values. Missing information may indeed be the information itself. The variable bool userWantsPizzaForDinner; for example might be used for true when the user said yes, false when the user declined and it might still be null when the user has not yet picked something. That's not a mistake, it's intentionally used and needs to be handled accordingly.
How do I fix it?
Find it
Use the stack trace that came with the error message to find out exactly which line the error was on. Then set a breakpoint on that line. When the program hits the breakpoint, inspect all the values of the variables. One of them is null, find out which one.
Fix it
Once you know which variable it is, find out how it ended up being null. Where did it come from? Was the value never set in the first place? Was the value another variable? How did that variable got it's value. It's like a line of breadcrumbs you can follow until you arrive at a point where you find that some variable was never set, or maybe you arrive at a point where you find that a variable was intentionally set to null. If it was unintentional, just fix it. Set it to the value you want it to have. If it was intentional, then you need to handle it further down in the program. Maybe you need another if to do something special for this case. If in doubt, you can ask the person that intentionally set it to null what they wanted to achieve.
simply the variable/function you are trying to access from the class does not exist
someClass.xyz();
above will give the error
NoSuchMethod: the method 'xyz' was called on null
because the class someClass does not exist
The following will work fine
// SomeClass created
// SomeClass has a function xyz
class SomeClass {
SomeClass();
void xyz() {
print('xyz');
}
}
void main() {
// create an instance of the class
final someClass = SomeClass();
// access the xyz function
someClass.xyz();
}

NoSuchMethodError: The getter 'hash' was called on null [duplicate]

I have some code and when I run it produces an error, saying:
NoSuchMethod: the method 'XYZ' was called on null
What does that mean and how do I fix it?
Why do I get this error?
Example
As a real world comparison, what just happened is this conversation:
Hey, how much gas is left in the tank of the car?
What are you talking about, we don't have a car.
That is exactly what is happening in your program. You wanted to call a function like _car.getGasLevel(); but there is no car, the variable _car is null.
Obviously, in your program it might not be a car. It could be a list or a string or anything else really.
Technical explanation
You are trying to use a variable that is null. Either you have explicitly set it to null, or you just never set it at all, the default value is null.
Like any variable, it can be passed into other functions. The place where you get the error might not be the source. You will have to follow the leads from the actual null value to where it originally came from, to find what the problem is and what the solution might be.
null can have different meanings: variables not set to another value will be null, but sometimes null values are used by programmers intentionally to signal that there is no value. Databases have nullable fields, JSON has missing values. Missing information may indeed be the information itself. The variable bool userWantsPizzaForDinner; for example might be used for true when the user said yes, false when the user declined and it might still be null when the user has not yet picked something. That's not a mistake, it's intentionally used and needs to be handled accordingly.
How do I fix it?
Find it
Use the stack trace that came with the error message to find out exactly which line the error was on. Then set a breakpoint on that line. When the program hits the breakpoint, inspect all the values of the variables. One of them is null, find out which one.
Fix it
Once you know which variable it is, find out how it ended up being null. Where did it come from? Was the value never set in the first place? Was the value another variable? How did that variable got it's value. It's like a line of breadcrumbs you can follow until you arrive at a point where you find that some variable was never set, or maybe you arrive at a point where you find that a variable was intentionally set to null. If it was unintentional, just fix it. Set it to the value you want it to have. If it was intentional, then you need to handle it further down in the program. Maybe you need another if to do something special for this case. If in doubt, you can ask the person that intentionally set it to null what they wanted to achieve.
simply the variable/function you are trying to access from the class does not exist
someClass.xyz();
above will give the error
NoSuchMethod: the method 'xyz' was called on null
because the class someClass does not exist
The following will work fine
// SomeClass created
// SomeClass has a function xyz
class SomeClass {
SomeClass();
void xyz() {
print('xyz');
}
}
void main() {
// create an instance of the class
final someClass = SomeClass();
// access the xyz function
someClass.xyz();
}

getServerSideProps and mysql (RowDataPacket)

I'd like to do server side rendering with Next.js using the getServerSideProps method like explained in the docs.
The data should come from a database, so I'm using the mysql package. This results in the following error:
Error serializing `.assertions[0]` returned from `getServerSideProps` in "/assertion". Reason: `object` ("[object Object]") cannot be serialized as JSON. Please only return JSON serializable data types.
I think the reason for this is, because the query method from mysql returns special objects (RowDataPacket). The result that I'd like to pass to getServerSideProps looks like this when logged:
[ RowDataPacket { id: 1, title: 'Test' } ]
I can fix this error by wrapping the result with JSON.parse(JSON.stringify(result)) but this seems very odd to me.
So, my simple question is: How to use mysql.query and getServerSideProps correctly?
Or might this be an issue that should be addressed by Next.js?
Thank you
I've run into this issue myself. When I had the issue it wasn't related to MySQL. The problem is getServerSideProps() expects you to return a "JSON serializable data type" which basically means a Plain ol' JavaScript Object (POJO).
To fix it, simply create a new POJO to return. A few ways you can go are:
// using spread operator to create new object
const plainData = {
...queryResult
}
// recreating the object with plucked props
const plainData = {
title: queryResult.title,
content: queryResult.content
}
// data conversion (wax-on wax-off)
const plainData = JSON.parse(JSON.stringify(queryResult))
Your specific data is in an array so your simplest solution is the wax-on wax-off since it will support arrays. Otherwise you've got to map over it.
why tho?
You can see your object has RowDataPacket attached to it. This means it's an instance of RowDataPacket and NextJS doesn't allow any instances unless it strictly equals the Object.prototype (see related code)
This seems weird, but they have already described why it's necessary in a Github Issue. TL;DR dates cause issues client-side when the page hydrates.

Kotlin Bundle.putString not explicitly adding "String" but instead is "String?"

val args = Bundle()
args.putString("type", details.type)
navigator.navigate(context!!, findNavController(), Destination.TYPE, args)
I am quite confused as to why in the receiving fragment when I go to access the arguments I have passed through it is responding with...
val type: String = arguments.getString("type")
The arguments.getString is all underlined red and says "Required String Found String?" But how when I called method "putString"?!?
It is resulting in text not being rendered in the new fragment and I assume this is a nullability issue.
It's a matter of knowledge that is available in the receiving Fragment.
The Fragment is not aware of how its arguments were created (or modified) so it has to assume the "type" key you're looking for might not be in the arguments Bundle. That's why it returns a nullable (String?) result (the null value would mean absent in arguments).
Your fragment might be created in many places in your app and its arguments might have been modified in many places. We have no way of tracking that.
There are different solutions for this problem, depending on your approach in other parts of the code and how "confident" you are in creating of your Fragment.
I would usually choose a solution in which I assume setting the type is mandatory. Therefore if the type is absent - I fail fast. That would mean the Fragment was misused.
val type: String = arguments!!.getString("type")!!
The code above will crash if either:
a) arguments weren't set, or
b) String with type wasn't put in the arguments Bundle.
You are right, that is a : null ability issue.
First you should be sure if you are expecting a value, so try adding "?" or "!!", i would recommend "?", or go with the block of if {} else
To read the string safely you can use:
val type: String = arguments?.getString("type").orEmpty()
The orEmpty call at the end ensures that a valid String is returned even if either arguments or getString() returns null.
The method signature for getString() returns a nullable String. This is because at compile time, the compiler can't know if the value exists in the bundle or not. You will have the same issue when retrieving anything from any Map.
If you know for certain that the value in the bundle or map should exist at the time you call getString(), you can use the !! operator. That's what it's there for. When you know something should always be there, it is appropriate to want an exception to be thrown (in this case KNPE) if it's not there so you can easily find any programming error during testing.
isEmpty() or ?.let aren't helpful in this particular case because they would just be masking a programming error and making it harder to discover or debug.

Casting to String in Flutter (Why doesn't it work? Plausibly syntax-errors)

Okay, I'm certain this is stupid simple, but google is not being kind to me today, lol.
So I've tried every variant of a method to cast a firebase IdTokenResult into a string, as it's required for the program I'm writing, and nothing seems to work. They are all giving me compiler errors, or run-time errors and not proceeding.
Exampled of things I've tried
String result = tokenResult as String; // Run-Time error, wrong sub-type
String result = tokenResult.toString(); // Build-error, can't be assigned to a variable of type...
and everything I find about the "cast()" command only talks about lists, and doesn't let me actually convert this value into a string.
I can PRINT it as a string to the console, but that doesn't really help me in any way shape or form. So... How the heck can I do this?
I thinkg you are using this getIdTokenResult(forceRefresh?: boolean): Promise<IdTokenResult> which returns IdTokenResult so thats why it giving you run time error, you need to take token property from the tokenResult which is of String dataType String result = tokenResult.token;

Resources