ข้อผิดพลาดของ SDK ผู้ดูแลระบบแบ่งออกเป็น 2 หมวดหมู่ ดังนี้
- ข้อผิดพลาดในการเขียนโปรแกรม: ข้อผิดพลาดเหล่านี้เป็นข้อผิดพลาดในการเขียนโปรแกรมและการกำหนดค่าใน
แอปพลิเคชันของผู้ใช้ ส่วนใหญ่ข้อผิดพลาดมักเกิดจากการใช้งาน SDK ที่ไม่ถูกต้อง
(เช่น การส่ง
null
ไปยังเมธอดที่ไม่ยอมรับค่าnull
) และ ข้อผิดพลาดอื่นๆ ในการกำหนดค่าที่ระดับโปรเจ็กต์ Firebase หรือ SDK (ไม่มี ข้อมูลเข้าสู่ระบบ สตริงรหัสโปรเจ็กต์ไม่ถูกต้อง เป็นต้น) - ข้อผิดพลาดของ API: รายการเหล่านี้ ข้อผิดพลาดต่างๆ ที่กู้คืนได้ ซึ่งเกิดขึ้นภายในการใช้งาน SDK ข้อผิดพลาดที่เกิดในบริการแบ็กเอนด์ของ Firebase และชั่วคราวอื่นๆ (เช่น การหมดเวลา) ที่อาจเกิดขึ้นขณะเรียกใช้ RPC
Admin SDK จะส่งสัญญาณข้อผิดพลาดในการตั้งโปรแกรมโดยแสดงข้อผิดพลาดของระบบ เกี่ยวกับแพลตฟอร์มที่เป็นปัญหา
- Java: แสดงอินสแตนซ์ของ
IllegalArgumentException
,NullPointerException
หรือข้อผิดพลาดประเภท รันไทม์ในตัวที่คล้ายกัน - Python: เพิ่มอินสแตนซ์ของ
ValueError
,TypeError
หรือข้อผิดพลาดในตัวประเภทอื่นๆ - ไป: แสดงผลข้อผิดพลาดทั่วไป
- .NET: ส่งอินสแตนซ์ของ
ArgumentException
,ArgumentNullException
หรือ ประเภทข้อผิดพลาดในตัวที่คล้ายกัน
ในกรณีส่วนใหญ่ คุณไม่ควรจัดการกับข้อผิดพลาดด้านการเขียนโปรแกรมอย่างชัดเจน แต่ คุณควรแก้ไขโค้ดและการกำหนดค่าเพื่อหลีกเลี่ยงข้อผิดพลาดในการเขียนโปรแกรม ลองพิจารณาข้อมูลโค้ด Java ต่อไปนี้
String uid = getUserInput();
UserRecord user = FirebaseAuth.getInstance().getUser(uid);
หากเมธอด getUserInput()
แสดงผล null
หรือสตริงว่าง
FirebaseAuth.getUser()
API แสดงผล IllegalArgumentException
แทนที่จะเป็น
เพื่อจัดการเรื่องนี้อย่างชัดเจน คุณจะสามารถลดปัญหาได้โดยการตรวจสอบ
เมธอด getUserInput()
จะไม่แสดงผลสตริง UID ที่ไม่ถูกต้อง หากไม่ใช่
ให้ใช้การตรวจสอบอาร์กิวเมนต์ที่จำเป็นในโค้ดของคุณเองดังนี้
String uid = getUserInput();
if (Strings.isNullOrEmpty(uid)) {
log.warn("UID must not be null or empty");
return;
}
UserRecord user = FirebaseAuth.getInstance().getUser(uid);
โดยหลักการแล้วคืออย่าพยายามแก้ไขข้อผิดพลาดในการเขียนโปรแกรมอีกครั้ง การอนุญาตให้ดำเนินการล้มเหลวอย่างรวดเร็ว ความหมายของข้อผิดพลาดทางการเขียนโปรแกรมมักเป็นวิธีที่ดีที่สุดเนื่องจาก แสดงข้อบกพร่องในการเขียนโปรแกรมและข้อผิดพลาดในการกำหนดค่าระหว่างการพัฒนา ได้อย่างทันท่วงที "ล้มเหลว" ในบริบทนี้ การปล่อยให้ข้อผิดพลาด เผยแพร่ไปยังเครื่องจัดการข้อผิดพลาดร่วมในแอปพลิเคชันของคุณ หรือเพียงแค่บันทึกข้อผิดพลาด เพื่อวัตถุประสงค์ในการตรวจสอบ ตามด้วยการสิ้นสุดการดำเนินการในปัจจุบัน (แอปพลิเคชันไม่ควรขัดข้อง) โดยทั่วไปแล้ว ให้ดำเนินการตามข้อผิดพลาด การจัดการแนวทางปฏิบัติที่ดีที่สุดในภาษาโปรแกรมและแอปพลิเคชันของคุณ เพียงเท่านี้ก็เพียงพอแล้วในการจัดการกับ
ตามปกติ การจัดการข้อผิดพลาดส่วนใหญ่ของคุณจะเน้นที่การจัดการ API ข้อผิดพลาด ข้อผิดพลาดเหล่านี้บางส่วนสามารถเรียกคืนได้ เช่น ข้อผิดพลาดที่เกิดจาก บริการที่ใช้งานไม่ได้ชั่วคราว และบริการบางส่วนอาจมีความคาดหมายในระหว่าง ขั้นตอนการดำเนินโปรแกรมตามปกติ เช่น การตรวจหาโทเค็นรหัสที่ไม่ถูกต้องหรือหมดอายุ ส่วนที่เหลือของคู่มือนี้จะสรุปว่า Admin SDK แสดงข้อผิดพลาดของ API ดังกล่าวอย่างไร และตัวเลือกต่างๆ ที่สามารถจัดการได้
โครงสร้างของข้อผิดพลาด API
ข้อผิดพลาดของ API ประกอบด้วยองค์ประกอบต่อไปนี้
- รหัสข้อผิดพลาด
- ข้อความแสดงข้อผิดพลาด
- รหัสข้อผิดพลาดของบริการ (ไม่บังคับ)
- การตอบกลับ HTTP (ไม่บังคับ)
เรารับประกันว่าข้อผิดพลาดของ API แต่ละรายการจะมีรหัสข้อผิดพลาดและข้อความแสดงข้อผิดพลาด ข้อผิดพลาด API บางรายการจะมีรหัสข้อผิดพลาดของบริการที่มีเฉพาะในส่วนของ API ด้วย ที่ทำให้เกิดข้อผิดพลาด เช่น ข้อผิดพลาดบางรายการที่เกิดจากการตรวจสอบสิทธิ์ Firebase API มีรหัสข้อผิดพลาดของบริการเฉพาะสำหรับ Firebase Auth หากข้อผิดพลาด เกิดจากการตอบกลับข้อผิดพลาด HTTP จากบริการแบ็กเอนด์ จะมีการตอบกลับ HTTP ที่เกี่ยวข้องด้วย ข้อมูลนี้สามารถใช้เพื่อตรวจสอบ ส่วนหัวและเนื้อหาที่ถูกต้องของคำตอบเดิม ซึ่งมีประโยชน์สำหรับ การแก้ไขข้อบกพร่อง การบันทึก หรือการใช้ตรรกะการจัดการข้อผิดพลาดที่ซับซ้อนยิ่งขึ้น
การใช้ Admin SDK ทั้งหมดยกเว้น Node.js มี API ที่เปิดใช้การเข้าถึง ส่วนประกอบข้างต้นของข้อผิดพลาด API
ประเภทข้อผิดพลาดและ API ตามภาษา
Java
ข้อผิดพลาดทั้งหมดของ API ใน Java จะขยายคลาส FirebaseException
คุณสามารถเข้าถึง
รหัสข้อผิดพลาด ข้อความแสดงข้อผิดพลาด และการตอบกลับ HTTP ที่ไม่บังคับจากคลาสพื้นฐานนี้
public class FirebaseException extends Exception {
@NonNull
public ErrorCode getErrorCode() {
// ...
}
@NonNull
public String getMessage() {
// ...
}
@Nullable
public IncomingHttpResponse getHttpResponse() {
// ...
}
}
API ที่แสดงรหัสข้อผิดพลาดของบริการจะมีคลาสย่อยเฉพาะ API ของ
FirebaseException
เช่น เมธอดสาธารณะทั้งหมดใน FirebaseAuth
API
ได้รับการประกาศว่าส่งอินสแตนซ์ FirebaseAuthException
คุณสามารถเข้าถึง
รหัสข้อผิดพลาดของบริการจากคลาสที่ได้มานี้
public class FirebaseAuthException extends FirebaseException {
@Nullable
public AuthErrorCode getAuthErrorCode() {
// ...
}
}
Python
ใน Python ข้อผิดพลาดทั้งหมดของ API จะขยายค่า exceptions.FirebaseError
คุณเข้าถึงรหัสข้อผิดพลาด ข้อความแสดงข้อผิดพลาด และ HTTP ที่ไม่บังคับได้
การตอบกลับจากคลาสพื้นฐานนี้
class FirebaseError(Exception):
@property
def code(self):
# ...
@property
def message(self):
# ...
@property
def http_response(self):
# ...
นอกจากนี้ Python Admin SDK ยังมีคลาสที่ได้รับแยกต่างหากสำหรับรหัสข้อผิดพลาดแต่ละรายการด้วย เราเรียกข้อผิดพลาดเหล่านี้ว่าคลาสข้อผิดพลาดแพลตฟอร์ม
class InvalidArgumentError(FirebaseError):
# ...
class NotFoundError(FirebaseError):
# ...
คุณสามารถตรวจจับ FirebaseError
ในโค้ดและตรวจสอบ code
ของโค้ดนั้น หรือ
ดำเนินการตรวจสอบ isinstance()
กับคลาสข้อผิดพลาดของแพลตฟอร์ม หรือคุณสามารถเขียน
เพื่อตรวจจับประเภทข้อผิดพลาดที่เฉพาะเจาะจงของแพลตฟอร์มโดยตรง วิธีการหลังคือ
ก็มีแนวโน้มที่จะทำให้โค้ดการจัดการข้อผิดพลาดอ่านง่ายขึ้น
API ที่แสดงรหัสข้อผิดพลาดของบริการจะระบุคลาสย่อยเฉพาะ API ของแพลตฟอร์ม
คลาสของข้อผิดพลาด เช่น เมธอดแบบสาธารณะทั้งหมดในโมดูล auth
อาจส่ง
ประเภทข้อผิดพลาดเฉพาะ API เช่น auth.UserNotFoundError
และ
auth.ExpiredIdTokenError
class UserNotFoundError(exceptions.NotFoundError):
# …
class ExpiredIdTokenError(exceptions.InvalidArgumentError):
# ...
Go
Go Admin SDK มีแพ็กเกจ errorutils
ซึ่งมีชุดของ
ฟังก์ชันที่อนุญาตให้ทดสอบรหัสข้อผิดพลาด
package errorutils
func IsInvalidArgument(err error) bool {
// ...
}
func IsNotFound(err error) bool {
// ...
}
ข้อความแสดงข้อผิดพลาดเป็นเพียงสตริงที่แสดงผลโดยฟังก์ชัน Error()
ของ
การตอบกลับ HTTP ที่ไม่บังคับสามารถเข้าถึงได้โดยการเรียกใช้
ฟังก์ชัน errorutils.HTTPResponse()
ซึ่งแสดงผล *http.Response
คุณสามารถส่ง nil
หรือค่าข้อผิดพลาดอื่นๆ ไปยังการตรวจสอบข้อผิดพลาดได้อย่างปลอดภัย
ในแพ็กเกจ errorutils
จะแสดงผล true
หากอาร์กิวเมนต์อินพุต
มีรหัสข้อผิดพลาดที่เป็นปัญหา และแสดงผล false
สำหรับทุกอย่าง
ทั้งหมด ฟังก์ชัน HTTPResponse()
มีลักษณะการทำงานที่คล้ายกัน แต่ยกเว้นฟังก์ชันกลับ
nil
จากเดิม false
API ที่แสดงรหัสข้อผิดพลาดของบริการจะทำให้มีการตรวจสอบข้อผิดพลาดเฉพาะ API
ในแพ็กเกจที่เกี่ยวข้อง เช่น แพ็กเกจ auth
จะให้ฟังก์ชัน IsUserNotFound()
และ IsExpiredIDTokenError()
.NET
ใน .NET ข้อผิดพลาดทั้งหมดของ API ให้ขยาย FirebaseException
คุณสามารถเข้าถึง
รหัสข้อผิดพลาดของแพลตฟอร์ม ข้อความแสดงข้อผิดพลาด และการตอบกลับ HTTP ที่ไม่บังคับจากฐานนี้
public class FirebaseException : Exception {
public ErrorCode ErrorCode { get; }
public String Message { get; }
public HttpResponseMessage HttpResponse { get; }
}
API ที่แสดงรหัสข้อผิดพลาดของบริการจะมีคลาสย่อยเฉพาะ API ของ
FirebaseException
เช่น เมธอดสาธารณะทั้งหมดใน API ของ FirebaseAuth
ได้รับการประกาศว่าส่งอินสแตนซ์ FirebaseAuthException
คุณสามารถเข้าถึง
รหัสข้อผิดพลาดของบริการจากคลาสที่ได้มานี้
public class FirebaseAuthException : FirebaseException {
public AuthErrorCode AuthErrorCode { get; }
}
รหัสข้อผิดพลาดของแพลตฟอร์ม
รหัสข้อผิดพลาดคือข้อผิดพลาดทั่วไปในบริการ Firebase และ Google Cloud Platform ทั้งหมด ตารางต่อไปนี้สรุปรหัสข้อผิดพลาดของแพลตฟอร์มที่เป็นไปได้ทั้งหมด นี่คือ เป็นรายการแบบคงที่ และคาดว่าจะไม่มีการเปลี่ยนแปลงเป็นเวลานาน
ไม่ถูกต้อง | ไคลเอ็นต์ระบุอาร์กิวเมนต์ไม่ถูกต้อง |
FAILED_PRECONDITION | ไม่สามารถดำเนินการตามคำขอในสถานะปัจจุบันของระบบ เช่น การลบไดเรกทอรีที่ไม่ว่าง |
ช่วงที่ไม่มีช่วง | ไคลเอ็นต์ระบุช่วงไม่ถูกต้อง |
ไม่มีการตรวจสอบสิทธิ์ | คำขอไม่ได้รับการตรวจสอบสิทธิ์เนื่องจากไม่มีโทเค็น OAuth ไม่ถูกต้อง หรือหมดอายุ |
PERMISSION_DENIED | ไคลเอ็นต์มีสิทธิ์ไม่เพียงพอ กรณีนี้อาจเกิดขึ้นเนื่องจากโทเค็น OAuth ไม่มีขอบเขตที่ถูกต้อง ไคลเอ็นต์ไม่มีสิทธิ์ หรือไม่ได้เปิดใช้ API สำหรับโปรเจ็กต์ไคลเอ็นต์ |
NOT_FOUND | ไม่พบทรัพยากรที่ระบุ หรือคำขอถูกปฏิเสธเนื่องจากเหตุผลที่ไม่เปิดเผย เช่น การอนุญาตพิเศษ |
ความขัดแย้ง | ความขัดแย้งในการดำเนินการพร้อมกัน เช่น ความขัดแย้งแบบ read-modify-write ใช้บริการเดิมเพียงไม่กี่บริการเท่านั้น บริการส่วนใหญ่ใช้ ABORTED หรือ ALREADY_EXISTS แทนการดำเนินการนี้ โปรดดูเอกสารเฉพาะบริการเพื่อดูว่าต้องจัดการใดในโค้ดของคุณ |
ล้มเลิกแล้ว | ความขัดแย้งในการดำเนินการพร้อมกัน เช่น ความขัดแย้งแบบ read-modify-write |
มีอยู่อยู่แล้ว | ทรัพยากรที่ไคลเอ็นต์พยายามสร้างมีอยู่แล้ว |
RESOURCE_EXHAUSTED | โควต้าทรัพยากรหมดหรือถึงขีดการจำกัดอัตราคำขอ |
ยกเลิกแล้ว | ไคลเอ็นต์ยกเลิกคำขอ |
การสูญเสียข้อมูล | ข้อมูลสูญหายโดยกู้คืนไม่ได้หรือข้อมูลเสียหาย ไคลเอ็นต์ควรรายงานข้อผิดพลาดดังกล่าวไปยังผู้ใช้ |
ไม่ทราบ | ข้อผิดพลาดของเซิร์ฟเวอร์ที่ไม่รู้จัก ซึ่งโดยทั่วไปจะเป็นข้อบกพร่องเกี่ยวกับเซิร์ฟเวอร์
รหัสข้อผิดพลาดนี้กำหนดให้กับข้อผิดพลาดการแยกวิเคราะห์การตอบกลับเฉพาะเครื่อง (unmarshal) ด้วย และข้อผิดพลาด I/O อื่นๆ ในระดับต่ำอีกมากมายที่วินิจฉัยได้ยาก |
ภายใน | ข้อผิดพลาดภายในเซิร์ฟเวอร์ ซึ่งโดยทั่วไปจะเป็นข้อบกพร่องเกี่ยวกับเซิร์ฟเวอร์ |
ไม่พร้อมให้บริการ | ไม่พร้อมให้บริการ ปกติแล้วเซิร์ฟเวอร์ขัดข้องชั่วคราว
รหัสข้อผิดพลาดนี้ยังได้รับการระบุให้กับข้อผิดพลาดเกี่ยวกับเครือข่ายภายในด้วย (ถูกปฏิเสธการเชื่อมต่อ ไม่มีเส้นทางไปยังโฮสต์) |
DEADLINE_EXCEEDED | เกินกำหนดเวลาในการส่งคำขอแล้ว กรณีนี้จะเกิดขึ้นก็ต่อเมื่อผู้โทรกำหนดเวลาที่สั้นกว่ากำหนดเวลาเริ่มต้นของ API เป้าหมาย (กล่าวคือ กำหนดเวลาที่ขอไม่เพียงพอที่เซิร์ฟเวอร์จะดำเนินการตามคำขอ) และคำขอไม่เสร็จภายในกำหนดเวลาดังกล่าว
ระบบจะกำหนดรหัสข้อผิดพลาดนี้ให้กับการเชื่อมต่อภายในเครื่องและระยะหมดเวลาในการอ่านด้วย |
API ส่วนใหญ่สามารถส่งผลให้เกิดรหัสข้อผิดพลาดข้างต้นเพียงบางส่วน ไม่ว่าในกรณีใดก็ตาม คุณ ไม่จำเป็นต้องจัดการรหัสข้อผิดพลาดเหล่านี้ทั้งหมดอย่างชัดแจ้ง นำเครื่องจัดการข้อผิดพลาดไปใช้ แอปพลิเคชันส่วนใหญ่จะสนใจเฉพาะ รหัสข้อผิดพลาด 1-2 รายการและถือว่ารายการอื่นๆ เป็นข้อผิดพลาดทั่วไปที่ไม่สามารถกู้คืนได้ ล้มเหลว
รหัสข้อผิดพลาดเฉพาะบริการ
Firebase Auth
ใบรับรองล้มเหลว | ดึงข้อมูลใบรับรองคีย์สาธารณะที่ต้องใช้เพื่อยืนยัน JWT (โทเค็นรหัสหรือคุกกี้เซสชัน) ไม่สำเร็จ |
อีเมลที่มีอยู่ | มีผู้ใช้ที่ใช้อีเมลที่ระบุนี้แล้ว |
EXPIRED_ID_TOKEN | โทเค็นรหัสที่ระบุให้กับ verifyIdToken() หมดอายุแล้ว
|
EXPIRED_SESSION_COOKIE | คุกกี้เซสชันที่ระบุไว้ใน verifySessionCookie() หมดอายุ
|
โดเมนลิงก์ไม่ถูกต้อง | โดเมนลิงก์แบบไดนามิกที่ระบุไม่ได้รับการกำหนดค่าหรือให้สิทธิ์สำหรับโปรเจ็กต์ปัจจุบัน เกี่ยวข้องกับ API ลิงก์การดำเนินการของอีเมล |
รหัสไม่ถูกต้อง | โทเค็นรหัสที่ระบุให้กับ verifyIdToken() ไม่ถูกต้อง
|
COOKIE ไม่ถูกต้อง | คุกกี้เซสชันที่ระบุให้กับ verifySessionCookie() ไม่ถูกต้อง
|
PHONE_NUMBER_ALREADY_EXISTS | มีผู้ใช้ที่ใช้หมายเลขโทรศัพท์ที่ระบุนี้แล้ว |
REVOKED_ID_TOKEN [โทเค็น] | โทเค็นรหัสที่ระบุให้กับ verifyIdToken() ถูกเพิกถอนแล้ว
|
REVOKED_SESSION_COOKIE | คุกกี้เซสชันที่ระบุให้กับ verifySessionCookie() หมดอายุแล้ว
|
UNAUTHORIZED_ดำเนินการต่อ_URL | โดเมนของ URL ดำเนินการต่อไม่ได้อยู่ในรายการที่อนุญาต เกี่ยวข้องกับ API ลิงก์การดำเนินการของอีเมล |
ผู้ใช้ไม่พบ | ไม่พบบันทึกผู้ใช้สำหรับตัวระบุที่ระบุ |
Firebase Cloud Messaging
ข้อผิดพลาด THIRD_PARTY_AUTH_ERROR | ใบรับรอง APNs หรือคีย์ API การตรวจสอบสิทธิ์พุชจากเว็บไม่ถูกต้องหรือขาดหายไป |
ไม่ถูกต้อง | อาร์กิวเมนต์อย่างน้อย 1 รายการที่ระบุในคำขอไม่ถูกต้อง |
ภายใน | ข้อผิดพลาดภายในเซิร์ฟเวอร์ |
TOTAL_EXCEEDED แล้ว | ข้อความเป้าหมายที่ส่งเกินขีดจำกัด |
ผู้ส่ง_ID_MISMATCH | รหัสผู้ส่งที่ได้รับการตรวจสอบสิทธิ์จะแตกต่างจากรหัสผู้ส่งสำหรับโทเค็นการลงทะเบียน โดยปกติแล้วหมายความว่าผู้ส่งและโทเค็นการลงทะเบียนเป้าหมายไม่ได้อยู่ในโปรเจ็กต์ Firebase เดียวกัน |
ไม่พร้อมให้บริการ | บริการของ Cloud Messaging ไม่พร้อมใช้งานชั่วคราว |
ไม่ได้ลงทะเบียน | อินสแตนซ์ของแอปถูกยกเลิกการลงทะเบียนจาก FCM โดยปกติแล้วหมายความว่าโทเค็นการลงทะเบียนอุปกรณ์ที่ใช้จะใช้ไม่ได้อีกต่อไปและจะต้องใช้โทเค็นใหม่ |
การลองใหม่อัตโนมัติ
Admin SDK จะพยายามแก้ไขข้อผิดพลาดบางอย่างอีกครั้งโดยอัตโนมัติก่อนที่จะแสดงข้อผิดพลาดเหล่านั้น ให้แก่ผู้ใช้ โดยทั่วไปแล้ว ระบบจะพยายามลองโหลดข้อผิดพลาดประเภทต่อไปนี้อีกครั้งอย่างชัดเจน
- ข้อผิดพลาด API ทั้งหมดที่เกิดจากการตอบกลับ HTTP 503 (บริการไม่พร้อมใช้งาน)
- ข้อผิดพลาด API บางรายการที่เกิดจากการตอบกลับ HTTP 500 (ข้อผิดพลาดภายในเซิร์ฟเวอร์)
- ข้อผิดพลาด I/O ระดับต่ำส่วนใหญ่ (ถูกปฏิเสธการเชื่อมต่อ รีเซ็ตการเชื่อมต่อ ฯลฯ)
SDK จะลองแก้ไขข้อผิดพลาดข้างต้นแต่ละรายการอีกครั้งสูงสุด 5 ครั้ง (ความพยายามครั้งแรก + 4 ครั้ง) โดยมี Exponential Backoff คุณดำเนินการลองอีกครั้งได้ ในระดับแอปพลิเคชันหากคุณต้องการ แต่โดยทั่วไปแล้ว ต้องระบุ
ลองอีกครั้ง - หลังจากการสนับสนุน
การติดตั้งใช้งาน Go และ .NET ของ Admin SDK จะมาพร้อมการรองรับ
จัดการส่วนหัว HTTP Retry-After
กล่าวคือ หากการตอบกลับข้อผิดพลาดที่ส่งโดย
เซิร์ฟเวอร์แบ็กเอนด์มีส่วนหัว Retry-After
มาตรฐาน SDK จะ
เมื่อลองใหม่ตราบใดที่ระยะเวลารอที่ระบุไม่ใช่
ยาว หากส่วนหัว Retry-After
ระบุระยะเวลารอนานมาก SDK
จะข้ามการลองใหม่และแสดงข้อผิดพลาดของ API ที่เหมาะสม
ปัจจุบัน Python Admin SDK ยังไม่รองรับส่วนหัว Retry-After
และ
รองรับเฉพาะ Exponential Backoff อย่างง่าย
ตัวอย่างการจัดการข้อผิดพลาด API
การใช้เครื่องจัดการข้อผิดพลาดทั่วไป
ในกรณีส่วนใหญ่ สิ่งที่คุณต้องการคือเครื่องจัดการข้อผิดพลาดทั่วไป เพื่อป้องกันไม่ให้การไหลเวียนของโปรแกรมสิ้นสุดลงโดยไม่คาดคิดเนื่องด้วย ข้อผิดพลาดของ API เครื่องจัดการข้อผิดพลาดดังกล่าวมักจะบันทึก ข้อผิดพลาดไว้เพื่อการตรวจสอบ หรือเรียกใช้กิจวัตรการจัดการข้อผิดพลาดเริ่มต้นอื่นๆ สำหรับ API ทั้งหมดที่พบ ผู้ใช้ไม่จำเป็นต้องสนใจรหัสข้อผิดพลาดต่างๆ หรือ ที่อาจทำให้เกิดข้อผิดพลาด
Java
try {
FirebaseToken token = FirebaseAuth.getInstance().verifyIdToken(idToken);
performPrivilegedOperation(token.getUid());
} catch (FirebaseAuthException ex) {
System.err.println("Failed to verify ID token: " + ex.getMessage());
}
Python
try:
token = auth.verify_id_token(idToken)
perform_privileged_pperation(token.uid)
except exceptions.FirebaseError as ex:
print(f'Failed to verify ID token: {ex}')
Go
token, err := client.VerifyIDToken(ctx, idToken)
if err != nil {
log.Printf("Failed to verify ID token: %v", err)
return
}
performPrivilegedOperation(token)
.Net
try
{
var token = await FirebaseAuth.DefaultInstance.VerifyIdTokenAsync(idToken);
PerformPrivilegedOperation(token.getUid());
}
catch (FirebaseAuthException ex)
{
Conole.WriteLine($"Failed to verify ID token: {ex.Message}");
}
การตรวจสอบรหัสข้อผิดพลาด
ในบางกรณี คุณอาจต้องการตรวจสอบรหัสข้อผิดพลาดที่ถูกต้องและเรียกใช้ กิจวัตรการจัดการข้อผิดพลาดแบบ Context-Aware แบบต่างๆ ในตัวอย่างต่อไปนี้ เรา มีเครื่องจัดการข้อผิดพลาดที่บันทึกข้อความแสดงข้อผิดพลาดที่เฉพาะเจาะจงมากขึ้นตาม รหัสข้อผิดพลาดของบริการ
Java
try {
FirebaseToken token = FirebaseAuth.getInstance().verifyIdToken(idToken);
performPrivilegedOperation(token.getUid());
} catch (FirebaseAuthException ex) {
if (ex.getAuthErrorCode() == AuthErrorCode.ID_TOKEN_EXPIRED) {
System.err.println("ID token has expired");
} else if (ex.getAuthErrorCode() == AuthErrorCode.ID_TOKEN_INVALID) {
System.err.println("ID token is malformed or invalid");
} else {
System.err.println("Failed to verify ID token: " + ex.getMessage());
}
}
Python
try:
token = auth.verify_id_token(idToken)
perform_privileged_operation(token.uid)
except auth.ExpiredIdTokenError:
print('ID token has expired')
except auth.InvalidIdTokenError:
print('ID token is malformed or invalid')
except exceptions.FirebaseError as ex:
print(f'Failed to verify ID token: {ex}')
Go
token, err := client.VerifyIDToken(ctx, idToken)
if auth.IsIDTokenExpired(err) {
log.Print("ID token has expired")
return
}
if auth.IsIDTokenInvalid(err) {
log.Print("ID token is malformed or invalid")
return
}
if err != nil {
log.Printf("Failed to verify ID token: %v", err)
return
}
performPrivilegedOperation(token)
.Net
try
{
var token = await FirebaseAuth.DefaultInstance.VerifyIdTokenAsync(idToken);
PerformPrivilegedOperation(token.getUid());
}
catch (FirebaseAuthException ex)
{
if (ex.AuthErrorCode == AuthErrorCode.ExpiredIdToken)
{
Console.WriteLine("ID token has expired");
}
else if (ex.AuthErrorCode == AuthErrorCode.InvalidIdToken)
{
Console.WriteLine("ID token is malformed or invalid");
}
else
{
Conole.WriteLine($"Failed to verify ID token: {ex.Message}");
}
}
อีกตัวอย่างหนึ่งที่เราตรวจหารหัสข้อผิดพลาดทั้งระดับบนสุดและรหัสข้อผิดพลาดของบริการมีดังนี้
Java
try {
FirebaseMessaging.getInstance().send(createMyMessage());
} catch (FirebaseMessagingException ex){
if (ex.getMessagingErrorCode() == MessagingErrorCode.UNREGISTERED) {
System.err.println("App instance has been unregistered");
removeTokenFromDatabase();
} else if (ex.getErrorCode() == ErrorCode.Unavailable) {
System.err.println("FCM service is temporarily unavailable");
scheduleForRetryInAnHour();
} else {
System.err.println("Failed to send notification: " + ex.getMessage());
}
}
Python
try:
messaging.send(create_my_message())
except messaging.UnregisteredError:
print('App instance has been unregistered')
remove_token_from_database()
except exceptions.UnavailableError:
print('FCM service is temporarily unavailable')
schedule_for_retry_in_an_hour()
except exceptions.FirebaseError as ex:
print(f'Failed to send notification: {ex}')
Go
_, err := client.Send(ctx, createMyMessage())
if messaging.IsUnregistered(err) {
log.Print("App instance has been unregistered")
removeTokenFromDatabase()
return
}
if errorutils.IsUnavailable(err) {
log.Print("FCM service is temporarily unavailable")
scheduleForRetryInAnHour()
return
}
if err != nil {
log.Printf("Failed to send notification: %v", err)
return
}
.Net
try
{
await FirebaseMessaging.DefaultInstance.SendAsync(createMyMessage());
}
catch (FirebaseMessagingException ex)
{
if (ex.MessagingErrorCode == MessagingErrorCode.UNREGISTERED)
{
Console.WriteLine("App instance has been unregistered");
removeTokenFromDatabase();
}
else if (ex.ErrorCode == ErrorCode.Unavailable)
{
Console.WriteLine("FCM service is temporarily unavailable");
scheduleForRetryInAnHour();
}
else
{
Console.WriteLine($"Failed to send notification: {ex.Message}");
}
}
การเข้าถึงการตอบกลับ HTTP
ในบางกรณีซึ่งพบได้ไม่บ่อยนัก คุณอาจต้องตรวจสอบการตอบกลับข้อผิดพลาด HTTP ที่แสดงโดย บริการแบ็กเอนด์และดำเนินการจัดการข้อผิดพลาดบางอย่างกับบริการดังกล่าว SDK ผู้ดูแลระบบ จะแสดงทั้งส่วนหัวและเนื้อหาของการตอบกลับข้อผิดพลาดเหล่านี้ คำตอบ เนื้อหามักส่งคืนเป็นสตริงหรือลำดับไบต์ดิบ และสามารถ เป็นรูปแบบเป้าหมายที่จำเป็น
Java
try {
FirebaseMessaging.getInstance().send(createMyMessage());
} catch (FirebaseMessagingException ex){
IncomingHttpResponse response = ex.getHttpResponse();
if (response != null) {
System.err.println("FCM service responded with HTTP " + response.getStatusCode());
Map<String, Object> headers = response.getHeaders();
for (Map.Entry<String, Object> entry : headers.entrySet()) {
System.err.println(">>> " + entry.getKey() + ": " + entry.getValue());
}
System.err.println(">>>");
System.err.println(">>> " + response.getContent());
}
}
Python
try:
messaging.send(create_my_message())
except exceptions.FirebaseError as ex:
response = ex.http_response
if response is not None:
print(f'FCM service responded with HTTP {response.status_code}')
for key, value in response.headers.items():
print(f'>>> {key}: {value}')
print('>>>')
print(f'>>> {response.content}')
Go
_, err := client.Send(ctx, createMyMessage())
if resp := errorutils.HTTPResponse(err); resp != nil {
log.Printf("FCM service responded with HTTP %d", resp.StatusCode)
for key, value := range resp.Header {
log.Printf(">>> %s: %v", key, value)
}
defer resp.Body.Close()
b, _ := ioutil.ReadAll(resp.Body)
log.Print(">>>")
log.Printf(">>> %s", string(b))
return
}
.Net
try
{
await FirebaseMessaging.DefaultInstance.SendAsync(createMyMessage());
}
catch (FirebaseMessagingException ex)
{
var response = ex.HttpResponse
if response != null
{
Console.WriteLine($"FCM service responded with HTTP { response.StatusCode}");
var headers = response.Headers;
for (var entry in response.Headers)
{
Console.WriteLine($">>> {entry.Key}: {entry.Value}");
}
var body = await response.Content.ReadAsString();
Console.WriteLine(">>>");
Console.WriteLine($">>> {body}");
}
}