11//! Phabricator backend for submitting patch stacks.
22
33use std:: collections:: { HashMap , HashSet } ;
4- use std:: fmt:: { self , Display , Write } ;
4+ use std:: fmt:: { self , Debug , Display , Write } ;
55use std:: io;
66use std:: path:: PathBuf ;
77use std:: process:: { Command , Stdio } ;
@@ -51,7 +51,7 @@ impl Display for Id {
5151#[ serde( transparent) ]
5252struct Phid ( pub String ) ;
5353
54- #[ derive( Debug , Default , Serialize , Eq , PartialEq ) ]
54+ #[ derive( Clone , Debug , Default , Serialize , Eq , PartialEq ) ]
5555struct DifferentialQueryRequest {
5656 ids : Vec < Id > ,
5757 phids : Vec < Phid > ,
@@ -73,9 +73,24 @@ struct DifferentialEditTransaction {
7373#[ derive( Debug , Deserialize ) ]
7474struct ConduitResponse < T > {
7575 #[ serde( rename = "errorMessage" ) ]
76- #[ allow( dead_code) ]
7776 error_message : Option < String > ,
78- response : T ,
77+ response : Option < T > ,
78+ }
79+
80+ impl < T > ConduitResponse < T > {
81+ fn check_err ( self ) -> std:: result:: Result < T , String > {
82+ let Self {
83+ error_message,
84+ response,
85+ } = self ;
86+ match error_message {
87+ Some ( error_message) => Err ( error_message) ,
88+ None => match response {
89+ None => Err ( "(no error message)" . to_string ( ) ) ,
90+ Some ( response) => Ok ( response) ,
91+ } ,
92+ }
93+ }
7994}
8095
8196impl < T : Default > Default for ConduitResponse < T > {
@@ -163,6 +178,12 @@ pub enum Error {
163178 args : Vec < String > ,
164179 } ,
165180
181+ #[ error( "error when calling Conduit API with request {request:?}: {message}" ) ]
182+ Conduit {
183+ request : Box < dyn Debug + Send + Sync > ,
184+ message : String ,
185+ } ,
186+
166187 #[ error( "could not make transaction ID: {source}" ) ]
167188 MakeTransactionId { source : eyre:: Error } ,
168189
@@ -567,7 +588,7 @@ impl PhabricatorForge<'_> {
567588 fn query_revisions (
568589 & self ,
569590 request : & DifferentialQueryRequest ,
570- ) -> Result < ConduitResponse < Vec < DifferentialQueryRevisionResponse > > > {
591+ ) -> Result < Vec < DifferentialQueryRevisionResponse > > {
571592 // The API call seems to hang if we don't specify any IDs; perhaps it's
572593 // fetching everything?
573594 if request == & DifferentialQueryRequest :: default ( ) {
@@ -613,7 +634,11 @@ impl PhabricatorForge<'_> {
613634 output : String :: from_utf8_lossy ( & result. stdout ) . into_owned ( ) ,
614635 args : args. clone ( ) ,
615636 } ) ?;
616- Ok ( output)
637+ let response = output. check_err ( ) . map_err ( |message| Error :: Conduit {
638+ request : Box :: new ( request. clone ( ) ) ,
639+ message,
640+ } ) ?;
641+ Ok ( response)
617642 }
618643
619644 /// Query the dependencies of a set of commits from Phabricator (not locally).
@@ -644,10 +669,7 @@ impl PhabricatorForge<'_> {
644669 . filter_map ( |id| id. as_ref ( ) . cloned ( ) )
645670 . collect ( ) ;
646671
647- let ConduitResponse {
648- error_message : _,
649- response : revisions,
650- } = self . query_revisions ( & DifferentialQueryRequest {
672+ let revisions = self . query_revisions ( & DifferentialQueryRequest {
651673 ids : query_ids,
652674 phids : Default :: default ( ) ,
653675 } ) ?;
@@ -671,10 +693,7 @@ impl PhabricatorForge<'_> {
671693 // Convert the dependency PHIDs back into revision IDs.
672694 let dependency_ids: HashMap < Id , Vec < Id > > = {
673695 let all_phids: Vec < Phid > = dependency_phids. values ( ) . flatten ( ) . cloned ( ) . collect ( ) ;
674- let ConduitResponse {
675- error_message : _,
676- response : revisions,
677- } = self . query_revisions ( & DifferentialQueryRequest {
696+ let revisions = self . query_revisions ( & DifferentialQueryRequest {
678697 ids : Default :: default ( ) ,
679698 phids : all_phids,
680699 } ) ?;
@@ -810,15 +829,14 @@ impl PhabricatorForge<'_> {
810829 return Ok ( Ok ( ( ) ) ) ;
811830 }
812831
813- let ConduitResponse {
814- error_message : _,
815- response,
816- } = self . query_revisions ( & DifferentialQueryRequest {
832+ let revisions = self . query_revisions ( & DifferentialQueryRequest {
817833 ids : parent_revision_ids,
818834 phids : Default :: default ( ) ,
819835 } ) ?;
820- let parent_revision_phids: Vec < Phid > =
821- response. into_iter ( ) . map ( |response| response. phid ) . collect ( ) ;
836+ let parent_revision_phids: Vec < Phid > = revisions
837+ . into_iter ( )
838+ . map ( |response| response. phid )
839+ . collect ( ) ;
822840 let request = DifferentialEditRequest {
823841 id,
824842 transactions : vec ! [ DifferentialEditTransaction {
0 commit comments