Repository: louislam/uptime-kuma
File: server/monitor-types/dns.js (JavaScript)

Code before:
                parsed.add(e);
                continue;
            }

            // Otherwise, attempt to resolve hostname
            const [ v4, v6 ] = await Promise.allSettled([
                resolver.resolve4(e),
                resolver.resolve6(e),
            ]);

            const addrs = [
                ...(v4.status === "fulfilled" ? v4.value : []),
                ...(v6.status === "fulfilled" ? v6.value : []),
            ];

            if (!addrs.length) {
                log.error("DNS", `Invalid resolver server ${e}`);
                continue;
            }

            addrs.forEach(ip => parsed.add(ip));
        }

        if (!parsed.size) {
            throw new Error("No Resolver Servers");
        }
        return Array.from(parsed);
    }

    /**
     * Resolves a given record using the specified DNS server
     * @param {string} hostname The hostname of the record to lookup
     * @param {string[]} resolverServer Array of DNS server IP addresses to use
     * @param {string} resolverPort Port the DNS server is listening on
     * @param {string} rrtype The type of record to request
     * @returns {Promise<(string[] | object[] | object)>} DNS response
     */
    async dnsResolve(hostname, resolverServer, resolverPort, rrtype) {
        const resolver = new Resolver();
        resolver.setServers(resolverServer.map(server => `[${server}]:${resolverPort}`));
        return new Promise((resolve, reject) => {
            if (rrtype === "PTR") {
                resolver.reverse(hostname, (err, records) => {
                    if (err) {
                        reject(err);
                    } else {
                        resolve(records);
                    }
                });
            } else {
                resolver.resolve(hostname, rrtype, (err, records) => {

Review comment (suggestion):
```suggestion
        // only the resolver resolution can discard an adress
        // -> no special error message for only the net.isIP case is nessesary
        if (!parsed.size) {
            throw new Error("None of the configured resolver servers could be resolved to an IP address. Please provide a comma-separated list of valid resolver hostnames or IP addresses.");
        }
```

Code after:
        // Make promises to be resolved concurrently
        const promises = addresses.map(async (e) => {
            if (net.isIP(e)) { // If IPv4 or IPv6 addr, immediately return
                return [ e ];
            }

            // Otherwise, attempt to resolve hostname
            const [ v4, v6 ] = await Promise.allSettled([
                resolver.resolve4(e),
                resolver.resolve6(e),
            ]);

            const addrs = [
                ...(v4.status === "fulfilled" ? v4.value : []),
                ...(v6.status === "fulfilled" ? v6.value : []),
            ];

            if (!addrs.length) {
                log.error("DNS", `Invalid resolver server ${e}`);
            }
            return addrs;
        });

        // [[ips of hostname1],[ips hostname2],...]
        const ips = await Promise.all(promises);
        // Append all the ips in [[]] to a single []
        const parsed = ips.flat();

        // only the resolver resolution can discard an address
        // -> no special error message for only the net.isIP case is necessary
        if (!parsed.length) {
            throw new Error("None of the configured resolver servers could be resolved to an IP address. Please provide a comma-separated list of valid resolver hostnames or IP addresses.");
        }
        return parsed;
    }

    /**
     * Resolves a given record using the specified DNS server
     * @param {string} hostname The hostname of the record to lookup
     * @param {string[]} resolverServer Array of DNS server IP addresses to use
     * @param {string} resolverPort Port the DNS server is listening on
     * @param {string} rrtype The type of record to request
     * @returns {Promise<(string[] | object[] | object)>} DNS response
     */
    async dnsResolve(hostname, resolverServer, resolverPort, rrtype) {
        const resolver = new Resolver();
        resolver.setServers(resolverServer.map(server => `[${server}]:${resolverPort}`));
        if (rrtype === "PTR") {
            return await resolver.reverse(hostname);
        }
        return await resolver.resolve(hostname, rrtype);