কৌশলগুলি পরিচালনা করার ক্ষেত্রে ত্রুটি [বন্ধ]


108

আমি শুধু গো দিয়ে শুরু করছি। আমার কোডটিতে এর প্রচুর পরিমাণ রয়েছে:

   if err != nil {
      //handle err
   }

অথবা এটা

  if err := rows.Scan(&some_column); err != nil {
      //handle err
  }

গো-র ত্রুটিগুলি যাচাই ও পরিচালনা করার জন্য কিছু ভাল আইডিয়াম / কৌশল / সেরা-অনুশীলন রয়েছে?

পরিষ্কার করার জন্য সম্পাদনা করুন: আমি বেলিচিচিং করছি না বা পরামর্শ দিচ্ছি যে গো দল আরও ভাল কিছু নিয়ে আসে। আমি জিজ্ঞাসা করছি আমি কি এটি সঠিকভাবে করছি কিনা বা সম্প্রদায়টি যে প্রযুক্তি নিয়ে এসেছিল তা আমি হারিয়ে ফেলেছি? সবাইকে ধন্যবাদ.


4
না, আসলে নেই। এটি প্রায়শই আলোচিত বিষয় এবং একটি বুদ্ধিমান বিষয়। অনেকগুলি বিবর্তনের প্রস্তাবও ছিল। দলের উত্তরটি মনে হয় এটি একটি ভাল লিখিত কোডে সমস্যা হওয়া উচিত নয়।
সাগ্রেট

সম্পর্কিত: stackoverflow.com/questions/15397419/...

মনে রাখবেন যে এই সম্পর্কিত প্রশ্নটি আসলে এই প্রশ্নের মতো নয়। উত্তরগুলি খুব নির্দিষ্ট।
সাগ্রেট

এই বিরক্তির জন্য যুক্তিও রয়েছে: একটি প্রোগ্রাম দ্রুত লিখতে এটি শক্ত করে তোলে তবে কেবল ত্রুটিগুলি পুনর্বিবেচনা করে বাগ তৈরি করা আরও শক্ত করে তোলে।
অস্বীকার করেছেন সাগুরেট

আপনি জানতে পারেন অ্যান্ড্রু Gerrand এবং ব্র্যাড ফিত্জপ্যাট্রিক বেশী বা কম অনুরূপ ফ্যাশন যান মধ্যে একটি HTTP / 2 ক্লায়েন্ট সূত্রপাত লিখতে youtube.com/watch?v=yG-UaBJXZ80
Supreet শেঠি

উত্তর:


61

আপনার কোডটি ইডিয়োমেটিক এবং আমার মতে এটি উপলব্ধ সেরা অনুশীলন। কিছু নিশ্চিতরূপে দ্বিমত পোষণ করবে তবে আমি যুক্তি দিয়ে বলব যে এটি গোলংয়ের স্ট্যান্ডার্ড লাইব্রেরি জুড়ে দেখা শৈলী । অন্য কথায়, গো লেখকরা এভাবে ত্রুটি পরিচালনা করে লিখেন।


12
"যান লেখকরা এইভাবে পরিচালনা করার সময় ত্রুটি লেখেন" " আমার কাছে ভাল লাগছে।
gmoore

"কেউ কেউ নিশ্চিত হয়ে একমত হবে না" : আমি নিশ্চিত না যে কেউ বলবেন এটি আজকের সবচেয়ে ভাল অনুশীলন নয়। কিছু সিনট্যাক্স চিনি বা অন্যান্য পরিবর্তন জিজ্ঞাসা করে তবে আজ আমি মনে করি না যে কোনও গুরুতর কোডার অন্যথায় ত্রুটিগুলি পরীক্ষা করবে।
সাগ্রেট

@ অডিস্ট্রয়: ঠিক আছে, কেউ কেউ " এটি " বলে , অন্যরা এটি বলে "ত্রুটিগুলি ফিরতি মানগুলিতে পরিচালিত হয় ′ 70′ এর স্টাইল।" , এবং আরও ;-)
zzzz

2
@ জেএনএমএল এইভাবে ত্রুটিগুলি পরিচালনা করা ভাষা নকশার বিষয়, এটি একটি অত্যন্ত বিতর্কিত বিষয়। ভাগ্যক্রমে কয়েক ডজন ভাষা বেছে নিতে পারে।
ফুজ

4
আমাকে কীভাবে খুন করে তা হ'ল প্রতিটি ফাংশন কলের জন্য একই প্যাটার্নটি কীভাবে ব্যবহৃত হয়। এটি কোডটি কোথাও কোলাহলে তোলে এবং কোথাও কোনও তথ্য না হারিয়েই কোডটি সহজ করার জন্য সিনট্যাকটিক চিনির জন্য চিৎকার করছে, যা মূলত সংক্ষিপ্ততার সংজ্ঞা (যা আমি বিশ্বাস করি যে ভার্বোসটির চেয়ে উচ্চতর বৈশিষ্ট্য, তবে এটি তর্কাতীতভাবে বিতর্কযুক্ত) পয়েন্ট)। নীতিটি দুর্দান্ত, তবে সিনট্যাক্সটি কাঙ্ক্ষিত আইএমএইচও হতে অনেকগুলি ছেড়ে যায়। তবে অভিযোগ করা নিষিদ্ধ, সুতরাং আমি এখনই আমার কুল-এইড পান করব ;-)
টমাস

30

এই প্রশ্ন জিজ্ঞাসা করার ছয় মাস পরে রব পাইক ত্রুটিগুলি হ'ল মান হিসাবে শিরোনামে একটি ব্লগ পোস্ট লিখেছিলেন ।

সেখানে তিনি যুক্তি দেখান যে আপনাকে ওপি দ্বারা উপস্থাপিত উপায়ে প্রোগ্রাম করার দরকার নেই এবং স্ট্যান্ডার্ড লাইব্রেরিতে বেশ কয়েকটি জায়গার উল্লেখ আছে যেখানে তারা আলাদা প্যাটার্ন ব্যবহার করে।

অবশ্যই একটি ত্রুটি মানের সাথে জড়িত একটি সাধারণ বিবৃতি এটি শূন্য কিনা তা পরীক্ষা করা হয় তবে ত্রুটি মানের সাথে অন্যান্য যেগুলি করতে পারে এমন আরও অনেকগুলি জিনিস রয়েছে এবং অন্যান্য কিছু জিনিস প্রয়োগ করা আপনার প্রোগ্রামকে আরও ভাল করে তুলতে পারে, অনেকটাই বয়লারপ্লেটকে সরিয়ে দেয় your যদি উত্থাপিত হয় যদি প্রতিটি ত্রুটি বিবৃতি দিয়ে রোট দিয়ে পরীক্ষা করা হয়।

...

আপনার ত্রুটি পরিচালনা পরিচালনা সহজ করার জন্য ভাষাটি ব্যবহার করুন।

তবে মনে রাখবেন: আপনি যাই করুন না কেন, সর্বদা আপনার ত্রুটিগুলি পরীক্ষা করে দেখুন!

এটি একটি ভাল পড়া।


ধন্যবাদ! এটি পরীক্ষা করে দেখবে।
gmoore

নিবন্ধটি দুর্দান্ত, আমার কাছে প্রায় মোনাডের মতো শোনাচ্ছে।
ওয়াটারলিংক

@ ওয়াটারলিঙ্ক আপনার বিবৃতি অর্থহীন। একটি রাষ্ট্র রয়েছে এমন সমস্ত কিছু প্রায় মোনাড, আপনি যদি এটি কিছুটা বাদ দেন। এটিকে এন.ইউইকিপিডিয়া.আর / উইকি / নাল_অবজেক্ট_প্যাটার্নের সাথে তুলনা করা আরও দরকারী, আমি মনে করি।
ব্যবহারকারী 7610

@ ব্যবহারকারী 7610, একটি প্রতিক্রিয়ার জন্য ধন্যবাদ। আমি কেবল একমত হতে পারি
ওয়াটারলিঙ্ক

2
পাইক: "তবে মনে রাখবেন: আপনি যাই করুন না কেন, সর্বদা আপনার ত্রুটিগুলি পরীক্ষা করে দেখুন!" - এটি তাই 80s। ত্রুটিগুলি যে কোনও জায়গায় ঘটতে পারে, প্রোগ্রামারদের বোঝা বন্ধ করে পেটের পক্ষে ব্যতিক্রম গ্রহণ করতে পারে।
স্লাওমির

22

আমি জেএনএমএলের উত্তরের সাথে একমত হব যে তারা উভয়ই আইডেম্যাটিক কোড, এবং নিম্নলিখিতগুলি যুক্ত করুন:

আপনার প্রথম উদাহরণ:

if err != nil {
      //handle err
}

একাধিক রিটার্ন মান নিয়ে কাজ করার সময় আরও মুশকিল। উদাহরণ স্বরূপ:

val, err := someFunc()
if err != nil {
      //handle err
}
//do stuff with val

কেবলমাত্র errমানটির সাথে লেনদেন করার সময় আপনার দ্বিতীয় উদাহরণটি দুর্দান্ত শর্টহ্যান্ড । যদি ফাংশনটি কেবলমাত্র একটি ফেরত দেয় error, বা আপনি যদি ইচ্ছাকৃতভাবে মানগুলি বাদ দিয়ে অন্য মানগুলি উপেক্ষা করেন তবে এটি প্রযোজ্য error। উদাহরণস্বরূপ, এটি কখনও কখনও এমন ফাংশন Readerএবং Writerফাংশনগুলির সাথে ব্যবহৃত হয় যা intলিখিত বাইটগুলির সংখ্যার (কখনও কখনও অপ্রয়োজনীয় তথ্য) এবং একটি প্রদান করে error:

if _, err := f.Read(file); err != nil {
      //handle err
}
//do stuff with f

দ্বিতীয় ফর্মটি যদি একটি ইনিশিয়ালেশন স্টেটমেন্ট ব্যবহার করে বলে উল্লেখ করা হয়

তাই সর্বোত্তম অভ্যাসের ক্ষেত্রে, যতদূর আমি জানি ( "ত্রুটিগুলি" ব্যবহার করা ব্যতীত ) নতুন ত্রুটিগুলির প্রয়োজন হলে প্যাকেজটি ) আপনি গো-র মধ্যে আবট ত্রুটিগুলি জানার জন্য প্রয়োজনীয় সমস্ত কিছুই কভার করেছেন!

সম্পাদনা: আপনি যদি সত্যিই ব্যতিক্রম ছাড়া বাঁচতে পারবেন না, আপনি এগুলি নকল করতে পারেন defer, panic&recover


4

গো ফাংশনগুলির একটি সারি দিয়ে প্রবাহিত ত্রুটি পরিচালনা ও পাইপিংয়ের জন্য আমি একটি গ্রন্থাগার তৈরি করেছি।

আপনি এখানে পেতে পারেন: https://github.com/go-on/queue

এটিতে একটি কমপ্যাক্ট এবং ভার্বোস সিনট্যাকটিক ভেরিয়েন্ট রয়েছে। সংক্ষিপ্ত বাক্য গঠন এর উদাহরণ এখানে:

import "github.com/go-on/queue/q"

func SaveUser(w http.ResponseWriter, rq *http.Request) {
    u := &User{}
    err := q.Q(                      
        ioutil.ReadAll, rq.Body,  // read json (returns json and error)
    )(
        // q.V pipes the json from the previous function call
        json.Unmarshal, q.V, u,   // unmarshal json from above  (returns error)
    )(
        u.Validate,               // validate the user (returns error)
    )(
        u.Save,                   // save the user (returns error)
    )(
        ok, w,                    // send the "ok" message (returns no error)
    ).Run()

    if err != nil {
       switch err {
         case *json.SyntaxError:
           ...
       }
    }
}

ওভারহেডে সামান্য পারফরম্যান্স রয়েছে দয়া করে সচেতন হন, যেহেতু এটি প্রতিবিম্বটি ব্যবহার করে।

এছাড়াও এটি আইডেম্যাটিক গো কোড নয়, তাই আপনি এটি নিজের প্রকল্পগুলিতে ব্যবহার করতে চাইবেন, বা আপনার দল যদি এটি ব্যবহার করতে সম্মত হয়।


3
আপনি এটি করতে পারেন কেবল তার অর্থ এটি একটি ভাল ধারণা নয়। এটি চ্যান অফ দায়িত্বশীলতার প্যাটার্নের মতো দেখে মনে হচ্ছে পড়া (সম্ভবত মতামত) বেশি কঠিন। আমি এটি "আইডেম্যাটিক গো" নয় বলে পরামর্শ দেব। আকর্ষণীয়, যদিও।
স্টিভেন সরোকা

2

গোলং এবং অন্যান্য ভাষায় ত্রুটিগুলি পরিচালনা করার জন্য একটি "কৌশল" হ'ল কল স্ট্যাকের ত্রুটিগুলি পরিচালনা করার জন্য কল স্ট্যাকের পর্যাপ্ত উচ্চতা না হওয়া পর্যন্ত ধারাবাহিকভাবে ত্রুটিগুলি প্রচার করা। যদি আপনি সেই ত্রুটিটি খুব তাড়াতাড়ি পরিচালনা করার চেষ্টা করে থাকেন তবে আপনি সম্ভবত কোডটি পুনরাবৃত্তি করবেন। যদি আপনি এটি খুব দেরিতে পরিচালনা করেন তবে আপনি আপনার কোডটিতে কিছু ভেঙে ফেলবেন। গোলং এই প্রক্রিয়াটিকে অত্যন্ত সহজ করে তোলে কারণ এটি আপনি নির্ধারিত স্থানে কোনও ত্রুটি পরিচালনা করছেন বা প্রচার করছেন কিনা তা এটি স্পষ্ট করে দেয়।

আপনি যদি ত্রুটিটিকে উপেক্ষা করতে চলেছেন তবে একটি সাধারণ _ এই ঘটনাটি খুব স্পষ্টভাবে প্রকাশ করবে। আপনি যদি এটি পরিচালনা করছেন, তবে আপনি যে ত্রুটিটি পরিচালনা করছেন তা ঠিক কী ক্ষেত্রে পরিষ্কার তা আপনি যদি বিবৃতিতে এটি পরীক্ষা করে দেখবেন।

লোকেরা উপরে যেমন বলেছে, ত্রুটি আসলে একটি সাধারণ মান। এটি এরূপ হিসাবে আচরণ করে।


2

গো দেবতারা গো ২ তে ত্রুটি পরিচালনা করার জন্য একটি "খসড়া নকশা" প্রকাশ করেছেন এটি এর ত্রুটিগুলির প্রতিমাটি পরিবর্তনের লক্ষ্য করে:

ওভারভিউ এবং ডিজাইন

তারা ব্যবহারকারীদের কাছ থেকে মতামত চান!

প্রতিক্রিয়া উইকি

সংক্ষেপে, দেখে মনে হচ্ছে:

func f() error {
   handle err { fmt.Println(err); return err }
   check mayFail()
   check canFail()
}

আপডেট: খসড়া নকশাটি অনেক সমালোচনা পেয়েছে, সুতরাং আমি গো 2 এর জন্য বিবেচনা করার জন্য প্রয়োজনীয়তাগুলি খসড়া করেছি ত্রুটিটি একটি শেষ সমাধানের জন্য সম্ভাবনার মেনু সহ পরিচালনা করা Hand


1

বেশিরভাগ শিল্পে গোলং ডকুমেন্টেশনের ত্রুটি পরিচালনা ও গোতে উল্লিখিত মানক বিধিগুলি অনুসরণ করা হয় । এবং এটি প্রকল্পের জন্য ডক জেনারেশনকে সহায়তা করে।


এটি মূলত একটি লিঙ্কের উত্তর। আমি আপনাকে উত্তরে কিছু সামগ্রী যুক্ত করার পরামর্শ দিচ্ছি যাতে লিঙ্কটি অবৈধ হয়ে যায় তবে আপনার উত্তরটি এখনও কার্যকর হবে of
নিও

মূল্যবান মন্তব্যের জন্য আপনাকে ধন্যবাদ।
pschilakanti

0

নীচে গো-র জন্য ত্রুটি হ্যান্ডলিং হ্রাস করার বিষয়ে আমার নেওয়া হল, এইচটিটিপিএল ইউআরএল প্যারামিটারগুলি পাওয়ার সময় নমুনাটি হ'ল:

( Https://blog.golang.org/erferences-are-values থেকে প্রাপ্ত নকশার প্যাটার্ন )

type HTTPAdapter struct {
    Error *common.AppError
}

func (adapter *HTTPAdapter) ReadUUID(r *http.Request, param string, possibleError int) uuid.UUID {
    requestUUID := uuid.Parse(mux.Vars(r)[param])
    if requestUUID == nil { 
        adapter.Error = common.NewAppError(fmt.Errorf("parameter %v is not valid", param),
            possibleError, http.StatusBadRequest)
    }
    return requestUUID
}

একাধিক সম্ভাব্য পরামিতিগুলির জন্য এটি কল করা নীচের মতো হবে:

    adapter := &httphelper.HTTPAdapter{}
    viewingID := adapter.ReadUUID(r, "viewingID", common.ErrorWhenReadingViewingID)
    messageID := adapter.ReadUUID(r, "messageID", common.ErrorWhenReadingMessadeID)
    if adapter.Error != nil {
        return nil, adapter.Error
    }

এটি কোনও রূপালী বুলেট নয়, ক্ষয়ক্ষতিটি হ'ল যদি আপনার একাধিক ত্রুটি থাকে তবে আপনি কেবলমাত্র শেষ ত্রুটিটি পেতে সক্ষম হন।

তবে এই উদাহরণে এটি তুলনামূলক পুনরাবৃত্তি এবং কম ঝুঁকিপূর্ণ, তাই আমি কেবল সর্বশেষ সম্ভাব্য ত্রুটিটি পেতে পারি।


-1

আপনি পারেনঅনুরূপ ত্রুটিগুলির জন্য নিজের ত্রুটি পরিচালনার কোডটি সাফ করতে (যেহেতু ত্রুটিগুলি আপনাকে এখানে সতর্কতা অবলম্বন করতে হবে) এবং কোনও ফাংশন লিখতে পারেন যা আপনি ত্রুটিটি পরিচালনা করার জন্য পাস হওয়া ত্রুটির সাথে কল করেন call তখন আপনাকে প্রতিবার "if err! = Nil {}" লিখতে হবে না। আবার, এর ফলে কেবল কোডটি পরিষ্কার হয়ে যাবে, তবে আমি মনে করি না এটি কাজ করার মূর্তিযুক্ত পদ্ধতি।

আবার, মাত্র কারণ আপনার পারেন মানে এই নয় আপনি উচিত


-1

goerr ফাংশনগুলির সাথে ত্রুটিগুলি পরিচালনা করতে দেয়

package main

import "github.com/goerr/goerr"
import "fmt"

func ok(err error) {
    if err != nil {
        goerr.Return(err)
        // returns the error from do_somethingN() to main()
        // sequence() is terminated
    }
}

func sequence() error {
    ok(do_something1())
    ok(do_something2())
    ok(do_something3())

    return nil /// 1,2,3 succeeded
}
func do_something1() error { return nil }
func do_something2() error { return fmt.Errorf("2") }
func do_something3() error {
    fmt.Println("DOING 3")
    return nil
}

func main() {
    err_do_something := goerr.OR1(sequence)

    // handle errors

    fmt.Println(err_do_something)
}

Ick। এই জাতীয় যুক্তিকে হ্যান্ডল করার ক্ষেত্রে জটিল / আড়াল করা কোনও ভাল ধারণা আইএমও নয়। ফলস্বরূপ কোডটি (যা গোয়ারের উত্স প্রাক প্রসেসিংয়ের প্রয়োজন) ইডিয়োমেটিক গো কোডের চেয়ে পড়া / যুক্তি পড়া আরও শক্ত।
ডেভ সি

-4

আপনি যদি ত্রুটিগুলির যথাযথ নিয়ন্ত্রণ চান, তবে এটি সমাধান নাও হতে পারে তবে আমার জন্য বেশিরভাগ সময় কোনও ত্রুটি শো স্টপার হয় is

সুতরাং, আমি পরিবর্তে ফাংশন ব্যবহার করি।

func Err(err error) {
    if err!=nil {
        fmt.Println("Oops", err)
        os.Exit(1)
    }
}

fi, err := os.Open("mmm.txt")
Err(err)

এই জাতীয় বার্তাগুলির stderrপরিবর্তে যাওয়া উচিত stdout, তাই কেবল ব্যবহার করুন log.Fatal(err)বা log.Fatalln("some message:", err)। যেহেতু প্রায় mainসম্পূর্ণরূপে সম্পূর্ণ প্রোগ্রামটি শেষ করার সিদ্ধান্ত নেওয়া উচিত নয় (যেমন ফাংশন / পদ্ধতিগুলি থেকে ত্রুটি ফিরে পাওয়া, বাতিল করা উচিত নয়) এটি বিরল ক্ষেত্রে এটিই আপনি এটি করতে চান এটি পরিষ্কার এবং এটি পরিষ্কারভাবে করা ভাল (যেমন) if err := someFunc(); err != nil { log.Fatal(err) }) পরিবর্তে কোনও "সহায়ক" ফাংশন যা এটি কী করছে তা সম্পর্কে অস্পষ্ট নয় ("এরর" নামটি ভাল নয়, এটি প্রোগ্রামটি শেষ হতে পারে এমন কোনও ইঙ্গিত দেয় না)।
ডেভ সি

নতুন জিনিস শিখেছি! ধন্যবাদ আপনাকে ডেভসি
গন
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.