Hi! I have a data class ApiError(val message: Str...
# getting-started
e
Hi! I have a data class ApiError(val message: String). Is it possible to have the message run through some logic in the constructor before it is assigned?
m
With a data class you can not change the value. You could do some validation and you can create a new property based on it, but
message
must always match what was passed in. You could make it private and then expose a different property as public based on the constructor logic.
j
It depends on whether you want to change the message itself or just verify stuff. If it's just about checks, you can simply add an
init { }
block in the class with code that checks the message and throws if it doesn't match the expectations. If you want to transform the assigned message, then maybe this class is not a simple data holder. What would you expect
ApiError.copy(message = "new message")
to do? Should it transform the message as well? Should 2 `ApiError`s created with different messages but having the same underlying transformed message be considered equal? Should
toString()
reflect the original or the transformed message? Maybe you could consider making it a regular class and assign the
message
property after transformation:
Copy code
class ApiError(message: String) {
    val message = transform(message)
}
m
Yes if you need to do this, take some time to think about why you want it to be a data class.
e
Thanks for your replies. I changed it to a regular class and used Joffreys final suggestion. When I get an error and return this value to the user, it has \r\n elements in it. I figure Kotlins string serializer does this, but I'd like it to print a more readable message with newlines and tabs instead. I tried using
String.replace("\n", System.lineSeparator())
but it didn't really work. Any suggestion? I figure this has something to do with Jackson / the default serializer kotlin/spring boot is using?
j
If you don't like CRLF characters, why do you only replace LF? Also, if you replace them with the system line separator, it will not necessarily make more sense to the consumers of the API, because that line separator will be that of the server, which is potentially different from the client's. You may as well use some fixed choice for line endings (e.g. LF)
Note that Jackson or other JSON serializers simply convert LF and CR characters to their escape sequence (
\n
and
\r
) in JSON strings. They have to in order to conform to the spec. What you probably want (if you really want to change those) is to change the contents of the message before serialization
e
When I use the swagger of my API, I get a string that may look like
this is a string\r\n    This is an indented line\r\n    This is another indented line
. I'd like to format it to look the way it says it looks, but that's proving difficult. I don't know why it is like that.
j
Do you mean that it appears like that in the UI of swagger?
e
Yeah, this is particularily annoying when I display errors. Some errors come preformatted with indents per sub-error, which makes reading that message a bit of a task. If you "Try out" an endpoint in swagger, then in the resulting json of the ui it looks a bit wonky.
j
But the UI displays JSON, right? If that's the case, then this is expected. This is how the JSON is. When you display errors, the JSON is decoded, and line endings should be handled by whatever UI is showing the error.
If you want to provide extra information about the error (suberrors, error codes, context data etc) you should do so as part of the JSON structure, not using line endings and indentation within a plain string to give an adhoc structure
e
Makes sense. In that case it doesn't make sense to try what I am trying to do. It's kind of difficult to do what you're suggesting, because the error messages come from an integrated system and they are a plain string, even though it contains
n
sub-errors (yes they're all a part of the same string). I guess any users wanting a more readable message should just format it themselves (I only develop the api).
👌 1
j
Ok if those error strings are external, then you can either spend time parsing those strings and giving it a new structure, or just accept them as opaque strings that you simply forward to the user. It is perfectly fine to leave them as-is, especially if the users interact with the 3rd party system in other ways than with the API and expect messages in the same familiar format. But in that case, you shouldn't worry about
\r
and
\n
in there
e
Allright, agreed. I'll leave them as-is. Thanks for your help! 🙂