How to make data class copy with only properties initialized, to avoid StackOverflowError?

I have encountered a problem while trying to resolve problem with sensitive info in application logs — we have quite large data class object that at some time in processing flow we log. Problem is that this object contains properties email and phoneNumber, which we need to mask while logging to avoid leaking this data, for this we have two extension methods: String.maskEmail() and String.maskPhoneNumber().

That was my first solution, during which I encountered StackOverflowError:

data class Foo(
    val email: String = "email",
    val phoneNumber: String = "phoneNumber",
    // consider the fact that there is tens more props in real object
) {
    override fun toString() = withMaskedProps

    private val withMaskedProps: String = copy(
        email = email.maskEmail(), phoneNumber = phoneNumber.maskPhone(),
    ).toString()
}

In hindsight it’s obvious, because object at initialization recursively creates the copy, which creates the copy and etc. until we get the error.

The question is — can I achieve desired outcome without SO? I need the copied object to simply access property fields, without initializing anything else to not cause SO. And I want to make it universal, by overriding toString() and by ensuring that I don’t need to support new fields in string representation if new properties will be added to the data class.

11

If I understand correctly, your requirement is really to modify the behaviour of the toString() function. You want it to behave mostly as normal, but with some properties modified or redacted.

The toString() function of a data class is generated for you by the compiler. Unfortunately, there’s no way to override toString() while still retaining access to the compiler’s generated version. When the compiler sees that you’ve provided your own implementation, it will skip adding its own.

That means you can’t really “mix and match” in the way that you want. As you’ve discovered, making a copy() will let you redact the properties, but you still need to override toString() to insert that change. At that point, the original generated implementation of toString() is gone, and can’t be retrieved.

You can get around it by modifying the compiler’s generated toString() implementation, instead of adding an override. To do that, you’ll need a compiler plugin. There are at least two plugins designed for this purpose.

For example, using https://github.com/ZacSweers/redacted-compiler-plugin, you could annotate your class or its properties as @Redacted. There’s no need to create a copy().

@Retention(SOURCE)
@Target(PROPERTY, CLASS)
annotation class Redacted

data class Foo(
  @Redacted val email: String = "email",
  @Redacted val phoneNumber: String = "phoneNumber",
  …
)

The plugin has plenty of configuration options to let you customize how the redacted data will appear.

There’s also a similar https://github.com/aafanasev/sekret plugin.

Overriding toString in a data class necessarily means that you are giving up the automatically generated implementation. If you don’t want to do that, you can create your own PhoneNumber and Email classes that returns masked values from their toString.

@JvmInline
value class PhoneNumber(val value: String) {
    override fun toString() = "XXXX XXXX"
}
@JvmInline
value class Email(val value: String) {
    override fun toString() = "[email protected]"
}

data class Foo(
    val email: Email,
    val phoneNumber: PhoneNumber,
    // ...
)

I have made these value classes so that they get inlined on JVM, but they can also be regular classes or data classes if you prefer.

Change withMaskedProps to not be a property initialized at init.

Make it a getter. It will generate the copy only when withMaskedProps is called.

private val withMaskedProps: String get() = copy(...).toString()

Or make it lazy. It will generate the copy once, only if withMaskedProps is accessed.

private val withMaskedProps: String by lazy { copy(...).toString() }

1

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật