Quick Answer

Fix URI malformed errors: validate URI strings, handle encoding/decoding properly, and sanitize user input.

Understanding the Issue

The "URIError: URI malformed" occurs when JavaScript's URI decoding functions encounter invalid URI strings. This commonly happens with decodeURI(), decodeURIComponent(), or when working with URLs containing malformed percent-encoded characters. The error indicates that the URI string doesn't follow proper URI encoding standards. Understanding URI encoding rules, proper validation, and safe decoding practices prevents these errors when working with URLs and encoded data.

The Problem

This code demonstrates the issue:

Javascript Error
-- Problem 1: Decoding malformed URI strings
const malformedUri = "https://example.com/path%GG"; -- Invalid percent encoding
const decoded = decodeURI(malformedUri); -- URIError: URI malformed

-- Problem 2: Double decoding or invalid characters
const userInput = "search%E0%A4%A"; -- Incomplete percent encoding
const result = decodeURIComponent(userInput); -- URIError: URI malformed

-- Trying to decode already decoded string
const alreadyDecoded = "hello world";
const doubleDecoded = decodeURIComponent(alreadyDecoded); -- May cause issues

The Solution

Here's the corrected code:

Javascript Fixed
-- Solution 1: Safe URI decoding with error handling
function safeDecodeURI(uri) {
    try {
        return decodeURI(uri);
    } catch (error) {
        console.error("Failed to decode URI:", error.message);
        return uri; -- Return original if decoding fails
    }
}

function safeDecodeURIComponent(component) {
    try {
        return decodeURIComponent(component);
    } catch (error) {
        console.error("Failed to decode URI component:", error.message);
        return component; -- Return original if decoding fails
    }
}

-- Usage examples
const testUris = [
    "https://example.com/path%20with%20spaces",
    "https://example.com/path%GG", -- Invalid
    "search%E0%A4%85" -- Valid Hindi character
];

testUris.forEach(uri => {
    const decoded = safeDecodeURI(uri);
    console.log("Original:", uri, "Decoded:", decoded);
});

-- Solution 2: Proper URI validation and encoding
function isValidURI(str) {
    try {
        decodeURIComponent(str);
        return true;
    } catch (error) {
        return false;
    }
}

function sanitizeAndEncodeURI(input) {
    -- Remove or replace invalid characters
    const sanitized = input.replace(/[^ws-._~:/?#[]@!$&'()*+,;=]/g, "");
    return encodeURIComponent(sanitized);
}

-- URL parameter handling
function getUrlParameter(name) {
    const urlParams = new URLSearchParams(window.location.search);
    const param = urlParams.get(name);
    
    if (param && isValidURI(param)) {
        return safeDecodeURIComponent(param);
    }
    
    return param; -- Return as-is if invalid or null
}

-- Safe URL building
function buildUrl(baseUrl, params = {}) {
    const url = new URL(baseUrl);
    
    Object.entries(params).forEach(([key, value]) => {
        if (value !== null && value !== undefined) {
            url.searchParams.set(key, String(value));
        }
    });
    
    return url.toString();
}

-- Usage
const searchUrl = buildUrl("https://example.com/search", {
    query: "hello world",
    category: "electronics",
    price: 100
});

console.log("Built URL:", searchUrl);

-- Handle form data safely
function processFormData(formData) {
    const processedData = {};
    
    for (const [key, value] of formData.entries()) {
        if (isValidURI(value)) {
            processedData[key] = safeDecodeURIComponent(value);
        } else {
            processedData[key] = value;
        }
    }
    
    return processedData;
}

Key Takeaways

Always use try/catch when decoding URIs. Validate URI strings before decoding. Use URL and URLSearchParams APIs for safer URL manipulation. Sanitize user input before encoding.