Skip to content
This repository was archived by the owner on Mar 31, 2025. It is now read-only.

Attributes outside constructor in data class cause exception #654

@marthursson

Description

@marthursson

Describe the bug
When a data class that has a val not included in its constructor is referenced in documentation it causes an exception on startup:

 io.bkbn.kompendium.json.schema.exception.UnknownSchemaException: An unknown type was encountered: class com.example.SomeClass.  
    This typically indicates that a complex scalar such as dates,
      timestamps, or custom number representations such as BigInteger were not added as custom types when
      configuring the NotarizedApplication plugin.  If you are still seeing this error despite adding all
      required custom types, this indicates a bug in Kompendium, please open an issue on GitHub.
at io.bkbn.kompendium.json.schema.handler.SimpleObjectHandler$handle$required$3.invoke(SimpleObjectHandler.kt:75)
at io.bkbn.kompendium.json.schema.handler.SimpleObjectHandler$handle$required$3.invoke(SimpleObjectHandler.kt:70)
at kotlin.sequences.FilteringSequence$iterator$1.calcNext(Sequences.kt:171)
at kotlin.sequences.FilteringSequence$iterator$1.hasNext(Sequences.kt:194)
at kotlin.sequences.TransformingSequence$iterator$1.hasNext(Sequences.kt:214)
at kotlin.sequences.SequencesKt___SequencesKt.toSet(_Sequences.kt:849)
at io.bkbn.kompendium.json.schema.handler.SimpleObjectHandler.handle(SimpleObjectHandler.kt:85)

This is because SimpleObjectHandler attempts to find the attribute in the constructor and - failing to do so - throws an exception.

To Reproduce
Steps to reproduce the behavior:
Example data class:

data class SomeVO(
  val id: String,
  val name: String,
  val category: String,
) {
  val slug: String = id.toSlug()
}

The point of this approach is that this attribute should always have the exact same value depending on the id, so it should not be possible to send it to the constructor.

Expected behavior
The most reasonable behaviour would be to mark this attribute as required, because this only ever makes sense for return values, and the attribute will always have a value.

Additional context
There are obviously workarounds for this. One possible solution is to include the attribute in the constructor, with a default value:

data class SomeVO(
  val id: String,
  val name: String,
  val category: String,
  val slug: String = id.toSlug()
)

While this works, it is misleading because it indicates that any slug can be supplied to this class. It will also make the attribute optional in the schema, which is not the intention.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions