Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
86 views
in Technique[技术] by (71.8m points)

javascript - Throwing vs returning errors from Service classes

Is there a substantial difference between throwing vs returning an error from a service class?

class ProductService {
    async getProduct(id) {
        const product = await db.query(`...`)

        if (!product) {
            throw new ProductNotFoundError()
        }

        return product
    }

    // VS
    
    async getProduct(id) {
        const product = await db.query(`...`)

        if (!product) {
            return {
                data: null,
                error: new ProductNotFoundError()
            }
        }

        return {
            error: null,
            data: product
        }
    }
}

In this example, I'd like to raise an error message if a product is not found ( supposedly returning null is not enough, maybe I need to also provide additional info why the product is not found ).

As a general design principle, is there a preferred approach, are there any substantial pros/cons of both approaches?

I've been doing the throw new Error example, but then the code gets riddled with try/catch or .then/.catch statements, which make it somewhat harder to reason about.

What I don't particularly like about throwing errors is.. they are not unexpected. Obviously, I expect that a product might not be found, so I added a piece of logic to handle that part. Yet, it ends up being received by the caller the same way, for example, a TypeError is received. One is an expected domain error, the other one is unexpected exception.

In the first scenario, if I return an object with data and error properties ( or I can return an object with methods like isError, isSuccess and getData from each service, which is similar ), I can at least trust my code to not raise exceptions. If one happens to arise, then it will be by definition unexpected and caught by the global error handlers ( express middleware, for example ).

question from:https://stackoverflow.com/questions/65875386/throwing-vs-returning-errors-from-service-classes

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Is there a substantial difference between throwing vs returning an error from a service class?

Big difference. throw in an async function causes the promise that is returned from any async function to be rejected with that exception as the reject reason. Returning a value becomes the resolved value of the promise.

So, the big difference is whether the promise returns from the async function is resolved with a value or rejected with a reason.

As a general design principle, is there a preferred approach, are there any substantial pros/cons of both approaches?

Most people use promise rejections for unusual conditions where the caller would typically want to stop their normal code flow and pursue a different code path and use return values for something that is likely to continue the normal code flow. Think about chained promises:

x().then(...).then(...).catch(...)

If the condition should go immediately to the .catch() because something serious is busted, then a throw/rejection makes the most sense in x(). But, if the condition is just something to typically handle and continue the normal execution, then you would want to just return a value and not throw/reject.

So, you try to design x() to be the easiest for the expected use. A product not being found in the database is an expected possible condition, but it also might be something that the caller would want to abort the logic flow they were in, but the treatment of that condition will certainly be different than an actual error in the database.

As a reference example, you will notice that most databases don't treat a failure to find something in a query as an error. It's just a result of "not found".


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...