DRF Error Handler
A lightweight, zero-dependency Kotlin/JVM library that parses and normalizes structural Django REST Framework error responses into a flat, highly predictable control list for UI clients.
Django REST Framework (DRF) can return validation errors in wildly distinct schemas depending on whether the response triggered from a validation step, a nested object structure, array lists, permissions checks, or an unexpected server failure. While flexible on the server, this volatility introduces repetitive parse blocks inside mobile and desktop frontend architectures.
This library processes those payloads safely, ensuring your presentation layer receives uniform data maps instantly.
Features
- Parses standard field-level validation errors cleanly.
- Flattens deep nested serializer structures into human-readable dot notation path maps like
author.email. - Resolves complex list serialization failures into crisp indexed tokens like
items[1].quantity. - Implicitly groups structural exceptions containing
non_field_errorsor genericdetailproperties into accessible global contexts. - Safely extracts leaked internal Python
ErrorDetail("...", code="...")representations if exposed to the JSON output string. - Extracts fallback context from Django/DRF debug HTML screens gracefully for 404 or 500 exceptions, skipping layout elements entirely.
Installation
Import the package into your modern architecture build target directly from Maven Central:
repositories {
mavenCentral()
}
dependencies {
implementation("io.github.kallyas:drferrorhandler:0.1.1")
}
For explicit local iterations, publish the target package into your machine's local Maven context cache:
./gradlew publishToMavenLocal
Quick Start
Invoke the core package helper directly inside processing routes to map data strings safely:
import com.github.kallyas.DRFErrorHandler
val response = DRFErrorHandler.parse(
"""
{
"email": ["Enter a valid email address."],
"password": ["This field is required."]
}
""".trimIndent()
)
response.errors.forEach { error ->
println("${error.field}: ${error.message}")
}
Examples & Structures
Generic Exception Format
DRF exception parameters usually fall back onto a top-level detail value block:
val response = DRFErrorHandler.parse(
"""{"detail": "Authentication credentials were not provided."}"""
)
val message = response.globalErrors.firstOrNull()?.message
Nested Object Evaluation
Nested complex nodes map straight to flattened path strings:
val response = DRFErrorHandler.parse(
"""
{
"author": {
"email": ["Enter a valid email address."]
}
}
""".trimIndent()
)
val emailErrors = response.getErrorsForField("author.email")
List Processing Paths
Collection index integrity stays bound directly to deep component paths:
val response = DRFErrorHandler.parse(
"""
[
{},
{"title": ["This field is required."]}
]
""".trimIndent()
)
val titleErrors = response.getErrorsForField("[1].title")
Server Interceptor Preview
When the platform generates an operational system fallback view, extraction parses out core header properties:
val response = DRFErrorHandler.parse(htmlErrorBody)
val message = response.globalErrors.firstOrNull()?.message
// Emits: "OperationalError at /api/orders/"
API Reference
DRFErrorHandler.parse(jsonString: String): DRFErrorResponse
Main extraction path logic. Returns a safe wrapper container. This execution target will catch parsing structural parsing issues and output clean diagnostic fallbacks rather than bubbling run exceptions up through the app pipeline layer.
DRFError Model
data class DRFError(
val field: String?,
val message: String
)
The field configuration parameter maps directly to null whenever global issues or structural details block operations entirely without targeting single components.
DRFErrorResponse Methods
data class DRFErrorResponse(
val errors: List<DRFError>
) {
val hasErrors: Boolean
fun getErrorsForField(field: String): List<DRFError>
val globalErrors: List<DRFError>
}
Use Cases
Designed for multi-tier platform setups, form validation UI attachments, operational intercept networks, and diagnostic logging layers across lightweight clients.
Limitations
- The library operates purely as an operational parsing pipeline. All remote network requests and connection handles must be driven independently.
- Path mappings act as exact structural references (
items[0].namewill match distinct targets from generalitems.namepatterns).
Development & Validation
To run verification assertions locally across the package setup:
./gradlew test