Repository: ktorio/ktor
File: ktor-server/ktor-server-core/common/src/io/ktor/server/plugins/Errors.kt (Kotlin)

Code before:
 * Depending on child type it could be 4xx or 5xx status code. By default it will be 500 Internal Server Error.
 */
public abstract class ContentTransformationException(message: String) : IOException(message)

@OptIn(ExperimentalCoroutinesApi::class)
public class CannotTransformContentToTypeException(
    private val type: KType
) : ContentTransformationException("Cannot transform this request's content to $type"),
    CopyableThrowable<CannotTransformContentToTypeException> {

    override fun createCopy(): CannotTransformContentToTypeException =
        CannotTransformContentToTypeException(type).also {
            it.initCauseBridge(this)
        }
}

/**
 * Thrown when there is no conversion for a content type configured.
 * HTTP status 415 Unsupported Media Type will be replied when this exception is thrown and not caught.
 */
@OptIn(ExperimentalCoroutinesApi::class)
public class UnsupportedMediaTypeException(
    private val contentType: ContentType?
) : ContentTransformationException(
    contentType?.let { "Content type $it is not supported" }
        ?: "Content-Type header is required for multipart processing"
), CopyableThrowable<UnsupportedMediaTypeException> {

    override fun createCopy(): UnsupportedMediaTypeException = UnsupportedMediaTypeException(contentType).also {
        it.initCauseBridge(this)
    }
}

/**
 * Thrown when request body is larger than the set limit.
 * HTTP status 413 Payload Too Large will be replied when this exception is thrown and not caught.
 */
@OptIn(ExperimentalCoroutinesApi::class)
public class PayloadTooLargeException(
    private val sizeLimit: Long
) : ContentTransformationException("Request is larger than the limit of $sizeLimit bytes"),
    CopyableThrowable<PayloadTooLargeException> {

    override fun createCopy(): PayloadTooLargeException = PayloadTooLargeException(sizeLimit).also {
        it.initCauseBridge(this)
    }
}


Review comment (refactor):
Content-Type header may be required not only for multipart requests, we can remove this part

Code after:
 * Depending on child type it could be 4xx or 5xx status code. By default it will be 500 Internal Server Error.
 */
public abstract class ContentTransformationException(message: String) : IOException(message)

@OptIn(ExperimentalCoroutinesApi::class)
public class CannotTransformContentToTypeException(
    private val type: KType
) : ContentTransformationException("Cannot transform this request's content to $type"),
    CopyableThrowable<CannotTransformContentToTypeException> {

    override fun createCopy(): CannotTransformContentToTypeException =
        CannotTransformContentToTypeException(type).also {
            it.initCauseBridge(this)
        }
}

/**
 * Thrown when there is no conversion for a content type configured.
 * HTTP status 415 Unsupported Media Type will be replied when this exception is thrown and not caught.
 */
@OptIn(ExperimentalCoroutinesApi::class)
public class UnsupportedMediaTypeException(
    private val contentType: ContentType?
) : ContentTransformationException(
    contentType?.let { "Content type $it is not supported" }
        ?: "Content-Type header is required"
),
    CopyableThrowable<UnsupportedMediaTypeException> {

    override fun createCopy(): UnsupportedMediaTypeException = UnsupportedMediaTypeException(contentType).also {
        it.initCauseBridge(this)
    }
}

/**
 * Thrown when request body is larger than the set limit.
 * HTTP status 413 Payload Too Large will be replied when this exception is thrown and not caught.
 */
@OptIn(ExperimentalCoroutinesApi::class)
public class PayloadTooLargeException(
    private val sizeLimit: Long
) : ContentTransformationException("Request is larger than the limit of $sizeLimit bytes"),
    CopyableThrowable<PayloadTooLargeException> {

    override fun createCopy(): PayloadTooLargeException = PayloadTooLargeException(sizeLimit).also {
        it.initCauseBridge(this)
    }
}